PAGE
PAGE #
《软件体系结构》
实验报告
项目名称 实验2设计模式实验一
专业班级软件1403
学 号 3901140302
姓 名温睿诚
实验成绩:
批阅教师:
2016年 12月 23日
实验2设计模式实验一
实验学时: 4
每组人数: 1
实验类型:
3
(1 :
基础性
2:
综合性
3:
设计性
4 :研究性)
实验要求:
1
(1 :
必修
2:
选修
3:
其它)
实验类别:
3
(1 :
基础
2:
专业基础
3:
专业
4:其它)
、实验目的
1 ?熟练使用面向对象设计原则对系统进行重构;
熟练使用 PowerDesigner和任意一种面向对象编程语言实现几种常见的创建型设计
模式和结构型设计模式,包括简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、适
配器模式和组合模式,理解每一种设计模式的模式动机, 掌握模式结构,学习如何使用代码
实现这些模式。
、实验内容
1 ?在某图形库 API中提供了多种矢量图模板,用户可以基于这些矢量图创建不同的显 示图形,图形库设计人员设计的初始类图如下所示:
CircleTrian gleRecta ngle
Circle
Trian gle
Recta ngle
+ in it () :
+ in it () : void
+ setColor () : void
+ fill () : void
+ setSize () : void
+ display () : void
+ in it () : void
+ setColor () : void
+ fill () : void
+ setSize () : void
+ display () : void
+ in it () : void
+ setColor () : void
+ fill () : void
+ setSize () : void
+ display () : void
在该图形库中,每个图形类(如Circle、
在该图形库中,每个图形类(如
Circle、Triangle 等)的
init()方法用于初始化所创建的
Clie nt
图形,setColor()方法用于给图形设置边框颜色,fill()方法用于给图形设置填充颜色,setSize() 方法用于设置图形的大小, display。方法用于显示图形。
客户类(Client)在使用该图形库时发现存在如下问题:
由于在创建窗口时每次只需要使用图形库中的一种图形,因此在更换图形时需要修 改客户类源代码;
在图形库中增加并使用新的图形时需要修改客户类源代码;
客户类在每次使用图形对象之前需要先创建图形对象,有些图形的创建过程较为复 杂,导致客户类代码冗长且难以维护。
现需要根据面向对象设计原则对该系统进行重构,要求如下:
隔离图形的创建和使用,将图形的创建过程封装在专门的类中,客户类在使用图形 时无须直接创建图形对象,甚至不需要关心具体图形类类名;
客户类能够方便地更换图形或使用新增图形,无须针对具体图形类编程,符合开闭 原则。
绘制重构之后的类图并说明在重构过程中所运用的面向对象设计原则。
2?使用简单工厂模式设计一个可以创建不同几何形状 (Shape),如圆形(Circle)、矩形
(Rectangle)和三角形(Triangle)等的绘图工具类,每个几何图形均具有绘制 Draw()和擦除
Erase()两个方法,要求在绘制不支持的几何图形时,抛出一个 Un supportedShapeException
异常,绘制类图并编程模拟实现。
现需要设计一个程序来读取多种不同类型的图片格式,针对每一种图片格式都设计
一个图片读取器(ImageReader),如GIF图片读取器(GifReader)用于读取GIF格式的图片、JPG 图片读取器(JpgReader)用于读取JPG格式的图片。图片读取器对象通过图片读取器工厂 ImageReaderFactory来创建,ImageReaderFactory是一个抽象类,用于定义创建图片读取器 的工厂方法,其子类GifReaderFactory和JpgReaderFactory用于创建具体的图片读取器对象。
试使用工厂方法模式设计该程序, 绘制类图并编程模拟实现。需充分考虑系统的灵活性和可
扩展性。
某软件公司欲开发一套界面皮肤库,可以对桌面软件进行界面美化。不同的皮肤将 提供视觉效果不同的按钮、文本框、组合框等界面元素,其结构如下图所示:
该皮肤库需要具备良好的灵活性和可扩展性, 用户可以自由选择不同的皮肤, 开发人员 可以在不修改既有代码的基础上增加新的皮肤。
试使用抽象工厂模式设计该皮肤库, 绘制类 图并编程模拟实现。
使用单例模式的思想实现多例模式,确保系统中某个类的对象只能存在有限个,例 如两个或三个,设计并编写代码实现一个多例类。
使用单例模式设计一个多文档窗口(注:在 Java AWT/Swing开发中可使用
JDesktopPane和JinternalFrame来实现),要求在主窗体中某个内部子窗体只能实例化一次, 即只能弹出一个相同的子窗体,如下图所示,编程实现该功能。
(注:用C#或C++实现类似功能也可以)
现有一个接口 DataOperation 定义了排序方法 sort(int[])和查找方法 search(int[], int),
已知类 Quicksort的quickSort(int[])方法实现了快速排序算法,类 BinarySearch的 binarySearch(int[], int)方法实现了二分查找算法。试使用适配器模式设计一个系统,在不修
改源代码的情况下将类 QuickSort和类BinarySearch的方法适配到 DataOperation接口中。绘
制类图并编程实现。(要求实现快速排序和二分查找,使用对象适配器实现)
使用组合模式设计一个杀毒软件 (AntiVirus)的框架,该软件既可以对某个文件夹
(Folder)杀毒,也可以对某个指定的文件 (File)进行杀毒,文件种类包括文本文件 TextFile、
图片文件ImageFile、视频文件 VideoFile。绘制类图并编程模拟实现。
三、实验要求
选择合适的面向对象设计原则对系统进行重构,正确无误地绘制重构之后的类图;
结合实例,正确无误地绘制简单工厂模式、工厂方法模式、抽象工厂模式、单例模 式、适配器模式和组合模式的模式结构图;
使用任意一种面向对象编程语言实现简单工厂模式、工厂方法模式、抽象工厂模式、
单例模式、适配器模式和组合模式实例,代码运行正确无误。
四、实验步骤
选择合适的面向对象设计原则对系统进行重构, 使用PowerDesigner绘制重构之后的
类图;
结合实例,使用PowerDesigner绘制简单工厂模式实例结构图并用面向对象编程语言 实现该模式实例;
结合实例,使用PowerDesigner绘制工厂方法模式实例结构图并用面向对象编程语言 实现该模式实例;
结合实例,使用PowerDesigner绘制抽象工厂模式实例结构图并用面向对象编程语言 实现该模式实例;
结合实例,使用PowerDesigner绘制多例模式实例结构图并用面向对象编程语言实现 该模式实例;
结合实例,使用PowerDesigner绘制单例模式实例结构图并用面向对象编程语言实现 该模式实例。
结合实例,使用PowerDesigner绘制适配器模式实例结构图并用面向对象编程语言实 现该模式实例;
结合实例,使用PowerDesigner绘制组合模式实例结构图并用面向对象编程语言实现 该模式实例。
五、实验结果
重构之后的类图:
* F^lgiy<?xml version?<5hapeType? tiiangle^/sha^wT ypc >ffacioryCircieFactcryinltO iwdd*轻:诃日
* F^lgiy
<?xml version?
<5hapeType? tiiangle^/sha^wT ypc >
ffaciory
CircieFactcry
inltO iwdd
*轻:诃日
milD : vcrid
卜 setSize 0 询d
Ml即lay Q : vdd
fri angle Fa clary
■+ creatEShaffw 0 : Shape
ifijerlin-gie Factory+ < <0we<ride* > cnwrtrShapeO : Shape<<O^errikle>> inle
ifijerlin-gie Factory
+ < <0we<ride* > cnwrtrShapeO : Shape
<<O^errikle>> inle Q :帕Id
4 <<CHAerrkSe>* s^ltolor 0 : voQ
nil 0 ;vul'
t- < Q : toI-
4 : vdi
Triangle
+ ^?Own1de*> InftQ : void + leKoiar 0 rvold
t <*Ovcmde>> filIQ : vgid + 嘴 vOverrid巴a》"set^ire Q : void + ?<Owerride>i dreary D : raid
<<O¥errk*e>> Inh Q ;vold
<<QvprrKi?>> Q : vgid
* <Qvefride:>* fill 0 : void
+ <?Overrkle>> MTSize Q : void
4 *<OMerrkle>> display 0 : void
重构过程中所使用的面向对象设计原则及简要说明:
单一职责原则,使用工厂把类的创建和使用分开。
开闭原则,通过抽象工厂和抽象产品类,使得增加新的图形很方便。
里氏代换原则,客户端通过抽象工厂类编程, 运行时读取配置文件信息, 用具体工
厂类覆盖。
依赖倒转原则,客户端对抽象工厂类编程而不是具体工厂类编程。
迪米特法则,客户端只对三个类进行交互,不管以后增加多少个新的图形。
类图: public class ErrorShape implements Shape { private String type = nuII;
实现代码:-伽HQ ■"渲1
实现代码:
-伽HQ ■"渲1
■+ E?lmplc?r¥t?-> draw Q : wild
* <<lmp4eiTwnit>> Q :时1 日
令 ■= Constructor*> Error^iiijpe(String msg|
SimpitFdcwry
| +■ g049iapa (String :£hap?
*绡血旧咖 argsUR : void
XMUJtil
@Override
public void draw () throws UnSupportedShapeException { throw new UnSupportedShapeException( ”不支持"+type+"这种图形");
}
@Override
public void erase () {
}
public ErrorShape(String msg){
type =msg ;
}
}
public class Rect implements Shape {
@Override
public void draw () {
System. out .println("方形绘制”);
}
@Override
public void erase () {
System. out .println("方形擦除”);
}
public Rect(){
System. out .println("方形创建"); }
}
public class Triangle implements Shape { @Override
public void draw () {
System. out .println("三角形绘制"); }
@Override
public void erase () {
System. out .println("三角形擦除"); }
public Triangle(){
System. out .println("三角形创建"); }
}
public class SimpleFactory{
public static Shape getShape (String type) throws UnSupportedShapeException { Shape shape= nu II;
String stri ng=type.toLowerCase() ;
switch (string){
case "circle":
shape= new Circle();
break;
case "rectangle":
shape= new Rect();
break;
case "triangle":
shape= new Triangle();
break;
default :
shape= new ErrorShape(stri ng);
break;
}
return shape ;
}
public static void main (String[] args){
try {
Shape a ;
String type=XMLUtil. getShapeType ();
a=getShape (type);
a.draw();
a.erase();
} catch (Exception e){
e.pri ntStackTrace();
}
}
}
public class UnSupportedShapeException extends Exception {
public UnSupportedShapeException(String msg){
super (msg);
}
}
public class XMLUtil {
public static String getShapeType () {
try {
//创建文档对象
Docume ntBuilderFactory builderFactory =
3.类图:
GifReader+ <<lmplement>> readlmg (String fiileName) : void + <<Constructor>> GifReader 0Test■D-ReaderFartoryIrrihgiigeRsder+
GifReader
+ <<lmplement>> readlmg (String fiileName) : void + <<Constructor>> GifReader 0
Test
■D-
ReaderFartory
IrrihgiigeRsder
+ maiin (String ^rgsO) : void
+ createReadler 0 : ImageReader
+ readlmg (String fileName) : void
XMLUtil
+ getlmgReadeir 0 : Object
J ipg Reader
+ <<lmplement>> ireadlnng (String filename) : void
+ <<Constructor>> 」pg Reader 0
JPGReaderFactory
GIFReaderFartDiy+ <<)mplement>> cneateReader Q : ImageReiader
GIFReaderFartDiy
召 <<lrnplennerit >> create Reader Q : ImageReader
实现代码:
public class GIFReaderFactory implements ReaderFactory {
@Override
public ImageReader createReader () {
//配置环境等比如连接数据库
ImageReader reader= new GifReader();
//初始化reader的数据等
return reader ;
}
}
public class JPGReaderFactory implements ReaderFactory {
@Override
public ImageReader createReader () {
//配置环境等比如连接数据库
ImageReader reader= new JpgReader();
//初始化reader的数据等
return reader ;
}
}
public class GifReader implements ImageReader {
@Override
public void readImg (String fileName) {
System. out.println( "GIF 图片读取器读取"+fileName);
}
public GifReader(){}
}
public class JpgReader implements ImageReader {
@Override
public void readImg (String fileName) {
System. out.println( "JPG 图片读取器读取"+fileName);
}
public JpgReader(){}
}
public class XMLUtil {
public static Object getImgReader () {
try {
//创建文档对象
Docume ntBuilderFactory builderFactory =
DocumentBuilderFactory. newlnstanee ();
Docume ntBuilder builder = builderFactory .n ewDocume ntBuilder()
Document document = builder.parse( new File( "config.xml"));
NodeList no deList =
docume nt.getEleme ntsByTagName( "imgReaderFactory");
Node node = nodeList.item( O).getFirstChild();
String className = no de.getNodeValue().trim() ;
Class c=Class. forName (className);
Object o=c. newln sta nce() ;
return o;
} catch (Exception e) {
e.pri ntStackTrace();
return nu II;
}
}
}
public class Test {
public static void main (String[] args){
ReaderFactory factory= (ReaderFactory) XMLUtil. getImgReader ();
ImageReader reader=factory.createReader() ; reader.readImg( "1.");
}
}
类图:
XMLUtil
+ getlmgReader () : Object
*■ Button 0 : Button
Client I
1 : \
□
cre-ateTewtReldO : Te^rHeld
c reais ^uhekutdng O : Zuheku^ng
SpringSIdinFactQiy
+ cnea-teButton
+ cnea-teButton Q : Button
+ <<lm(3lerTwnt^> createTesctField 0 ! Textfiefd
+ <<lrinplei?nt!>> crFateZuhekijang {) : Zuhekuang
+ <<lmplenwnit>> create&utt&n () : Button
+ <simple-nwnt>> creat#TfKtFleldiO :TextReld
SpringT@jdFipldiSuimme 祝 uhekunngSummerfiuttonZuhekujinsz TexlFleldSpongButtonSpongButton
SpringT@jdFipldi
Suimme 祝 uhekunng
Summerfiutton
Zuhekujin
sz TexlFleld
SpongButton
SpongButton
实现代码:
public class Butt on {
}
public class TextField {
}
public class Zuhekuang {
}
public in terface SkinF actory {
Butt on createButt on ();
TextField createTextField ();
Zuhekuang createZuhekuang ();
}
public class Sprin gButt on exte nds Butt on {
}
public class SpringTextField extends TextField {
}
public class SpringZuhekuang extends Zuhekuang {
}
public class SpringSkinFactory implements SkinFactory {
@Override
public Butt on createButt on () {
return new SpringButton();
}
@Override
public TextField createTextField () {
return new SpringTextField();
}
@Override
public Zuhekuang createZuhekuang () {
return new SpringZuhekuang();
}
}
public class SummerButt on exte nds Butt on {
}
public class SummerTextField extends TextField {
}
public class SummerZuhekuang extends Zuhekuang {
}
public class SummerSkinFactory implements SkinFactory {
@Override
public Butt on createButt on () {
return new SummerButton();
}
@Override
类图:
duclis
J
Duoli
-INSTANCE NUMBER : int
-count - : int = INSTANCE_NUMBER - 1
-duolis : Duali|] = new Duoli[lNSTANCE NUMBER]
-<<statklnitializer>> _STATIC」NITIALIZER0 :?d
-<<Constructor> > Duoli 0
- getlnstance Q : Duoli
+ m^in (String arq^Q) : void
实现代码:
输出
加载Duoli这个类了
new Duoli() 了
new Duoli() 了
new Duoli() 了
desig nPattern.Duoli.Duoli@14ae5a5
desig nPattern.Duoli.Duoli@7f31245a
desig nPattern.Duoli.Duoli@6d6f6e28
desig nPattern.Duoli.Duoli@14ae5a5
类图:
MyJ Interna I Fra me
MyJFrameJB Litton :
MyJFrame
JB Litton : JButton
< c 匚onstru ctor> > MyJ Fra me Q
main (String argsQ) : void
-<<Constfuctor^> MyJInternalFrame (String titl氏 boolean resize boolean close)
+■ getln^tance O' : MyJlntemalFrame
目 HaldeirClass
MyJlnternalFrame;7Ha IderCla^s
-inBai 门氓 :iVly川 ntEmalFr 日 mtE ■ hew MyJ Interna I Fra me-C" tt/.tru 启也叮已)
实现代码:
7.类图:
I
p
a DataQperatlcn
+ tort (Int air[J) : bool?^in
+ search (int arrQ, int a) : boolean
实现代码:
public in terface DataOperati on {
boolean sort(int[] arr);
boolean search (int [] arr, int a);
}
public class BinarySearch {
public static boolean binarySearch (int[] arr, int a) {
return true;
}
}
public class QuickSort {
public static boolean quicksort (int[] a) {
return true;
}
}
public class DoAdapter implements DataOperation {
private QuickSort quickSort ;
private BinarySearch binarySearch ;
public DoAdapter(){
quickSort =new Quicksort。;
binarySearch =new BinarySearch();
}
@Override
public boolean sort (int[] arr) {
return quicksort .quicksort (arr);
}
@Override
public boolean search (int[] arr, int a) {
return binarySearch .binarySearch (arr ,a);
}
}
8.类图:
实现代码:
public abstract class AbstractFile { private Stri ng file name ;
public String getFilename () { return file name ;
}
public void setFile name (Stri ng file name) { this .file name = file name ;
}
public AbstractFile(String filename){ setFile name(file name) ;
}
public abstract void killVirus ();
}
public abstract class File extends AbstractFile { public File(Stri ng file name) { super (filename);
}
}
public class Folder extends AbstractFile {
private LinkedList<AbstractFile> files = new LinkedList<>();
public Folder(Stri ng file name) { super (filename);
}
public void add (AbstractFile file){
files .add(file);
}
private void killFiles (){
for (AbstractFile file: files)
file.killVirus();
}
@Override
public void killVirus () {
System. out.println("对文件夹"+super .getFilename()+ "下的文件进行杀毒 "); killFiles();
}
}
public class ImageFile extends File {
public ImageFile(Stri ng file name) { super (filename);
}
@Override
public void killVirus () {
System. out.println("对图片文件"+super .getFilename()+ "进行杀毒");
}
}
public class TextFile extends File {
public TextFile(Stri ng file name) { super (filename);
}
@Override
public void killVirus () {
System. out.println("对文本文件"+super .getFilename()+ "进行杀毒");
}
}
public class VideoFile extends File {
public VideoFile(Stri ng file name) { super (filename);
}
@Override
"进行杀毒
"进行杀毒");
System. out.println("对视频文件"+super .getFilename()+ }
}
public class Client {
public static void main (String[] args) {
AbstractFile a =
AbstractFile a1 =
new Folder("软件体系结构
nev
v Folder("实验二");
AbstractFile b =
new
TextFile( "1.txt");
AbstractFile c =
new
ImageFile( "2.jpg");
AbstractFile d =
new
VideoFile( "3.rmvb");
((Folder) a).add(a1);
((Folder) a1).add(b);
d.killVirus();
a.killVirus();
c.killVirus();
打印
对视频文件3.rmvb进行杀毒
对文件夹软件体系结构下的文件进行杀毒
对文件夹实验二下的文件进行杀毒
对文本文件1.txt进行杀毒
对图片文件2.jpg进行杀毒
六、实验小结
推荐访问:实验报告 实验 体系结构 中南大学 中南大学软件学院体系结构实验报告-实验2