《Java设计模式》课后习题参考答案_第1页
《Java设计模式》课后习题参考答案_第2页
《Java设计模式》课后习题参考答案_第3页
《Java设计模式》课后习题参考答案_第4页
《Java设计模式》课后习题参考答案_第5页
已阅读5页,还剩81页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《Java设计模式》课后习题参考答案

教材:刘伟.Java设计模式.北京:清华大学出版社,2018.

ISBN:9787302488316

【说明:本答案供参考,如有意见或建议,请通过电子邮箱weiliu_china@126.com与作者

联系!】

第1章设计模式概述

1.D

2.C

3.B

4.参见教材P5。

5.参见教材P6-P7。

6.参见教材P9-P10。

7.反模式(AntiPattems)是指那些导致开发出现障碍的负面模式,即在软件开发中普遍存在、

反复出现并会影响到软件成功开发的不良解决方案。反模式是关注于负面解决方案的软件研究

方向,揭示出不成功系统中存在的反模式有利于在成功系统中避免出现这些模式,有助于降低软

件缺陷和项目失败出现的频率。反模式清晰定义了大部分人在软件开发过程中经常会犯的一些错

误,根据视角的不同,可分为开发性反模式、架构性反模式和管理性反模式。

8.JDK中部分设计模式使用示例列举如下:

创建型模式:

(1)抽象工厂模式(AbstractFactory)

•java.util.Calendar#getInstance()

•java.util.Arrays#asList()

•java.util.ResourceBundle#getBundle()

•.URL#openConnection()

•java.sql.DriverManager#getConnection()

•java.sql.Connection#createStatement()

•java.sql.Statement#executeQuery()

•java.text.NumberFormat#getInstance()

•java.lang.management.ManagementFactory(所有getXXX。方法)

•java.nio.charset.Charset#forName()

•javax.xml.parsers.DocumentBuilderFactory#newInstance()

•javax.xml.transform.TransformerFactory#newInstance()

,javax.xml.xpath.XPathFactory#newInstance()

(2)建造者模式(Builder)

•java.lang.StringBuilder#append()

•java.lang.StringBuffer#append()

•java.nio.ByteBuffer#put()(CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer和

DoubleBuffer与之类似)

•javax.swing.GroupLayout.Group#addComponent()

•java.sql.PreparedStatement

1

•java.lang.Appendable的所有实现类

(3)工厂方法模式(FactoryMethod)

•java』ang.Object#toString()(在其子类中可以覆盖该方法)

•java.lang.Class#newInstance()

•java.lang.Integer#valueOf(String)(Boolean,Byte,Character,Short,Long,Float和

Double与之类似)

•java.lang.Class#forName()

•java.lang.reflect.Array#newInstance()

•java.lang.reflect.Constructoi^newInstanceO

(4)原型模式(Prototype)

•java.lang.Object#clone()(支持浅克隆的类必须实现java.lang.Cloneable接口)

(5)单例模式(Singleton)

•java.lang.Runtime#getRuntime()

•java.awt.Desktop#getDesktop()

结构型模式:

(1)适配器模式(Adapter)

•java.utiI.Arrays#asList()

•javax.swing.JTable(TableModel)

•java.io.InputStreamReader(InputStream)

,java.io.OutputStreamWriter(OutputStream)

•javax.xml.bind.annotation.adapters.XmlAdapter#marshal()

,javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()

(2)桥接模式(Bridge)

•AWT(提供了抽象层映射于实际的操作系统)

•JDBC

(3)组合模式(Composite)

•javax.swing.JComponent#add(Component)

•java.awt.Container#add(Component)

•java.util.Map#putAll(Map)

•java.util.List#addAll(Collection)

•java.util.Set#addAll(Collection)

(4)装饰模式(Decorator)

,java.io.BufferedlnputStream(InputStream)

•java.io.DatalnputStream(InputStream)

,java.io.BufferedOutputStream(OutputStream)

•java.util.zip.ZipOutputStream(OutputStream)

•java.utiLCollections#checked[List|Map|Set|SortedSet|SortedMap]()

(5)外观模式(Facade)

•java.lang.Class

•javax.faces.webapp.FacesServlet

(6)享元模式(Flyweight)

•java.lang.Integer#valueOf(int)

•java.lang.Boolean#valueOf(boolean)

•java.lang.Byte#valueOf(byte)

2

•java.lang.Character#valueOf(char)

(7)代理模式(Proxy)

•java.Iang.reflect.Proxy

•java.rmi.*

行为型模式:

(1)职责链模式(ChainofResponsibility)

•java.util.logging.Logger#log()

•javax.servlet.Filter#doFilter()

(2)命令模式(Command)

•java.lang.Runnable

•javax.swing.Action

(3)解释器模式(Interpreter)

•java.util.Pattern

•java.text.Normalizer

•java.text.Format

•javax.el.ELResolver

(4)迭代器模式(Iterator)

•java.util.Iterator

•java.util.Enumeration

(5)中介者模式(Mediator)

•java.util.Timer(fiffWscheduleXXX()方法)

•java.util.concurrent.Executor#execute()

•java.util.concurrent.ExecutorService(invokeXXX。和submit。方法)

•java.util.concurrent.ScheduledExecutorService(所有scheduleXXX。方法)

•java.lang.reflect.Method#invoke()

(6)备忘录模式(Memento)

,java.util.Date

•java.io.Serializable

•ponent.StateHolder

(7)观察者模式(Observer)

•java.util.Observer?java.util.Observable

•java.util.EventListener(所有子类)

•javax.servlet.http.HttpSessionBindingListener

•javax.servlet.http.HttpSessionAttributeListener

•javax.faces.event.PhaseListener

(8)状态模式(State)

•java.util.Iterator

•javax.faces.lifecycle.LifeCycle#execute()

(9)策略模式(Strategy)

•java.util.Comparator#compare()

•javax.servlet.http.HttpServlet

•javax.servlet.Filter#doFilter()

(10)模板方法模式(TemplateMethod)

•java.io.InputStream,java.io.OutputStream,java.io.Reader和java.io.Writer的所有非抽象

3

方法

•java.utiLAbstractList,java.util.AbstractSet^0java.util.AbstractMap的所有非抽象方法

•javax.servlet.http.HttpServlet#doXXX()

(11)访问者模式(Visitor)

•javax.lang.model.element.AnnotationValue和AnnotationVaiueVisitor

•javax.lang.model.element.Element和Elementvisitor

•javax.lang.model.type.TypeMirror和TypeVisitor

参见:http://www.iteye.eom/news/l8725和/questions/1673841/

examples-of-gof-design-patternso

第2章面向对象设计原则

l.BACDDC

2.C

3.D

4.D

5."封装变化点”可对应“开闭原则”「对接口进行编程”可对应“依赖倒转原则”,“多使用组合,

而不是继承”可对应“合成复用原则

6.类的粒度需满足单一职责原则,接口的粒度需满足接口隔离原则。

7.在面向对象设计中,正方形不能作为长方形的子类,具体分析过程如下:

classRectangle〃长方形

(

privatedoublewidth;

privatedoubleheight;

publicRectangle(doublewidth,doubleheight)

(

this.width=width;

this.height=height;

}

publicdoublegetHeight()

(

returnheight;

}

publicvoidsetHeight(doubleheight)

(

this.height=height;

)

publicdoublegetWidth()

(

returnwidth;

)

publicvoidsetWidth(doublewidth)

this.width=width;

4

classSquareextendsRectangle〃正方形

(

publicSquare(doublesize)

(

super(size,size);

)

publicvoidsetHeight(doubleheight)

(

super.setHeight(height);

super.setWidth(height);

)

publicvoidsetWidth(doublewidth)

(

super.setHeight(width);

super.setWidth(width);

classClient

(

publicstaticvoidmain(Stringargs[])

(

Rectangler;

r=newSquare(O.O);

r.setWidth(5.O);

r.setWidth(10.00);

doublearea=calculateArea(r);

if(50.00==area)

(

System.out.println("这是长方形或长方形的子类!");

)

else

(

System.out.println("这不是长方形!");

)

)

publicstaticdoublecalculateArea(Rectangler)

returnr.getHeight()*r.getWidth();

5

)

由代码输出可以得知,我们在客户端代码中使用长方形类来定义正方形对象,将输出“这不

是长方形!“,即将正方形作为长方形的子类,在使用正方形替换长方形之后正方形已经不

再是长方形,接受基类对象的地方接受子类对象时出现问题,违反了里氏代换原则,因此从面

向对象的角度分析,正方形不是长方形的子类,它们都可以作为四边形类的子类。关于该问题

的进一步讨论,大家可以参考其他相关资料,如BertrandMeyer的基于契约设计(Design

ByContract),在长方形的契约(Contract)中,长方形的长和宽是可以独立变化的,但是正方形

破坏了该契约。

8.重构方案如下所示:

在本重构方案中,将笔的大小和颜色设计为两个继承结构,两者可以独立变化,根据依赖

倒转原则,建立一个抽象的关联关系,将颜色对象注入到画笔中;再根据合成复用原则,画

笔在保持原有方法的同时还可以调用颜色类的方法,保持原有性质不变。如果需要增加一种新

的画笔或增加一种新的颜色,只需对应增加一个具体类即可,且客户端可以针对高层类Pen和

Color编程,在运行时再注入具体的子类对象,系统具有良好的可扩展性,满足开闭原则。

(注:本重构方案即为桥接模式)

第3章简单工厂模式

1.C

2.C

3.A

品类,Man、Woman和Robot充当具体产品类。

5.参考类图如下:

6

其中,Shape接口充当抽象产品,其子类Circle、Rectangle和Triangle等充当具体产品,

ShapeFactory充当工厂类。

第4章工厂方法模式

1.B

2.D

3.AB

4.参考类图如下所示:

其中,Car充当抽象产品,其子类BMW和Benz充当具体产品;CarFactory充当抽象工

厂,其子类BMWFactory和BenzFactory充当具体工厂。

5.抽象类/接口Chart充当抽象产品,其子类LineChart和BarChart充当具体产品;抽象类/

接口ChartFactory充当抽象工厂,其子类LineChartFactory和BarChartFactory充当具体工厂。

6.抽象类/接口Convertor充当抽象产品,其子类TXTConverlor、DBConvertor和

ExcelConvertor充当具体产品;抽象类/接口ConvertorCreator充当抽象工厂,其子类

TXTConvertorCreatorxDBConvertorCreator和ExcelConvertorCreator充当具体工厂。

参考类图如下:

7

7.参考类图如下:

ImageReader

+readlnage():void

AA

GifReaderJpgReader

+readlmage():void+readimage():void

A

|«create»

«create»

其中,ImageReaderFaclory充当抽象工厂,GifReaderFactory和JpgReaderFaclory充当具

体工厂,ImageReader充当抽象产品,GifReader和JpgReader充当具体产品。

第5章抽象工厂模式

1.D

2.D

3.A

4.参考类图如下所示:

8

其中,EFactory充当抽象工厂,HaierFactory和TCLFactory充当具体工厂,Television

和AirConditioner充当抽象产品,HaierTelevision>TCLTelevision^HaierAirConditioner和

TCLAirConditioner充当具体产品。

5.参考类图如下所示:

其中,接口DBFactory充当抽象工厂,其子类OracleFactory和MySQLFactory充当具体

工厂,接口Connection和Statement充当抽象产品,其子类OracleConnection、

MySQLConnection和OracleStatement>MySQLStatement充当具体产品。

6.参考类图如下所示:

其中,接口AbstractFactory充当抽象工厂,其子类SymbianFactory和AndroidFactory

充当具体工厂;Operationcontroller和Interfacecontroller充当抽象产品,其子类

SymbianOperationController、AndroidOperationController、SymbianlnterfaceController和

9

AndroidlnterfaceController充当具体产品。

7.参考类图如下所示:

其中,接口AbstractFactory充当抽象工厂,其子类WindowsFactory>UnixFactory和

LinuxFactory充当具体工厂;Text和Button充当抽象产品,其子类WindowsText、UnixText^

LinuxText和WindowsButton、UnixButton>LinuxButton充当具体产品。

第6章建造者模式

1.D

2.C

3.D

4.参考类图如下所示:

10

其中,Computer充当复合产品,ComputerBuilder充当抽象建造者,Notebook>Desktop

和Server充当具体建造者,ComputerAssembleDirector充当指挥者,其assemble。方法用于

定义产品的构造过程。

5.参考类图如下所示:

在该设计方案中,MainScreen是播放器的主界面,它是一个复合对象,包括菜单、播

放列表、主窗口和控制条等成员。ModeBuilder是一个抽象类,定义了一组抽象方法

buildXXX。用于逐步构造一个完整的MainScreen对象,getScreen()是工厂方法,用于返回一

个构造好的MainScreen对象。ScreenModeController充当指挥者,用于指导复合对象的创建,

其中construcl。方法封装了具体创建流程,并向客户类返回完整的产品对象。

11

第7章原型模式

1.A

2.D

3.C

4.参考类图如下所示:

°-Serializable

uaiaL/nan

-ds:DataSet

-color:Color

-no:int

ds

_______+setDataSet(DataSetds):void

+setColor(Colorcolor):void

+setNo(intno):void

+getDataSet():DataSet

+getColor():Color

+getNo():int

+display():void

+deepCIone():Object

在该设计方案中,DataChart类包含一个DataSet对象,在复制DataChart对象的同时将

复制DataSet对象,因此需要使用深克隆技术,可使用流来实现深克隆。

5.参考类图如下所示:

其中,OfficialDocument(抽象公文类)充当抽象原型类,其子类FAR(FeasibilityAnalysis

Report,可行性分析报告)和SRS(SoftwareRequirementsSpecification,软件需求规格说明

书)充当具体原型类,PrototypeManager充当原型管理器。核心代码如下:

importjava.util.*;

〃抽象公文接口,也可定义为抽象类,提供clone。方法的实现,将业务方法声明为抽象方

interfaceOfficialDocumentextendsCloneable{

publicOfficialDocumentclone();

12

publicvoiddisplayO;

〃可行性分析报告(FeasibilityAnalysisReport)类

classFARimplementsOfficialDocument{

publicOfficialDocumentclone()

{OfficialDocumentfar=

null;try{

far=(OfficialDocument)super.clone();

)

catch(CioneNotSupportedExceptione)

{System.out.println("不支持复制!");

}

returnfar;

)

publicvoiddisplayO{

System.out.println("《可行性分析报告》”);

〃软件需求规格说明书(SoftwareRequirementsSpecification)类

classSRSimplementsOfficialDocument{

publicOfficialDocumentclone()

{OfficialDocumentsrs=

null;try{

srs=(OfficialDocument)super.clone();

}

catch(CloneNotSupportedExceptione)

{System.out.println("不支持复制!

“);

)

returnsrs;

)

publicvoiddisplayO{

System.oul.println("《软件需求规格说明书》)

〃原型管理器(使用饿汉式单例实现)

classPrototypeManager{

〃定义一个Hashtable,用于存储原型对象

privateHashtableht=newHashtable();

privatestaticPrototypeManagerpm=newPrototypeManager();

13

〃为Hashtable增加公文对象

privatePrototypeManager()

{ht.put("far”,newFAR());

ht.put('*srs,,,newSRSQ);

)

〃增加新的公文对象

publicvoidaddOfficialDocument(Stringkey,OfficialDocumentdoc)

{ht.put(key,doc);

)

〃通过浅克隆获取新的公文对象

publicOfficialDocumentgetOfficialDocument(Stringkey)

{return((OfficialDocument)ht.get(key)).clone();

)

publicstaticPrototypeManagergetPrototypeManager()

{returnpm;

)

)

客户端代码如下所示:

classClient{

publicstaticvoidmain(Stringargs[]){

〃获取原型管理器对象

PrototypeManagerpm=PrototypeManager.getPrototypeManager();

OfficialDocumentdoc1,doc2,doc3,doc4;

docl=pm^etOfficialDocumentCTar'1);

docl.displayO;

doc2=pm.getOfficialDocument(“far");

doc2.display();

System.oul.println(doc1==doc2);

doc3=pm.getOfficialDocument(,'srsu);

doc3.display();

doc4=pm.getOfficialDocument(',srs,');

doc4.display();

System.out.println(doc3==doc4);

)

)

编译并运行程序,输出结果如下:

《可行性分析报告》

14

《可行性分析报告》

false

《软件需求规格说明书》

《软件需求规格说明书》

false

6.浅克隆参考类图如下所示:

AddressCjstoier

<----------o-addre沾:ddress

+clone():Object

本实例实现了浅克隆,Object类充当抽象原型类,Customer类充当具体原型类,浅克隆

只复制容器对象,不复制成员对象。Customer类的代码片段如下所示:

publicclassCustomerimplementsCloneable

{

privateAddressaddress=null;

publicCustomer()

(

this.address=newAddress();

)

〃浅克隆方法

publicObjectclone()

(

Objectobj=null;

try

{

obj=super.clone();

)

calch(CloneNotSupportedExceplione)

(

System.out.println("Clonefailure!");

)

returnobj;

)

〃其他代码省略

)

深克隆参考类图如下所示:

15

Serializable

本实例实现了深克隆,Customer和Address类均实现了Serializable接口,深克隆既复

制容器对象,又复制成员对象。Customer的代码如下所示:

importjava.io.*;

publicclassCustomerimplementsSerializable

(

privateAddressaddress=null;

publicCustomer()

(

this.address=newAddress();

)

〃深克隆方法

publicObjectdeepClone()throwslOException,ClassNotFoundException,

OptionalDataException

(

〃将对象写入流中

ByteArrayOutputStreambao=newByteArrayOutputStream();

ObjectOutputStreamoos=newObjectOutputStream(bao);

oos.writeObject(this);

〃将对象从流中取出

ByteArraylnputStreambis=newByteArraylnputStream(bao.toByteArrayO);

ObjectInputStreamois=newObjectlnputStream(bis);

return(ois.readObject());

)

〃其他代码省略

第8章单例模式

1.B

2.B

3.B

4.参见P1U-P114,可从延迟加载、线程安全、响应时间等角度进行分析与对比。5.

参见PU2-P113。

16

6.双重检查锁定方式实现代码参见Pl13;loDH方式实现代码参见Pl14。

7.参考类图如下:

其中,SubFrame类充当单例类,在其中定义了静态工厂方法getFrame。。

参考代码如下所示:

importjava.awt.*;

importjava.awt.event.*;

importjavax.swing.*;

importjavax.swing.event.*;

〃子窗口:单例类

classSubFrameextendsJInternalFrame

privatestaticSubFrameframe;〃静态实例

〃私有构造函数

privateSubFrame()

super("子窗体",true,true,true,false);

this.setLocation(20,20);//设置内部窗体位置

this.setSize(200,200);〃设置内部窗体大小

this.addInternalFrameListener(newMyIFListener());〃监听窗体事件

this.setVisible(true);

)

〃工厂方法,返回窗体实例public

staticSubFramegetFrame()

//如果窗体对象为空,则创建窗体,否则直接返回已有窗体

if(frame==null)

frame=newSubFrame();

returnframe;

)

〃事件监听器

17

classMylFListenerextendsInternalFrameAdapter

(

〃子窗体关闭时,将窗体对象设为null

publicvoidinternalFrameClosing(InternalFrameEvente)

(

if(frame!=null)

(

frame=null;

)

)

}

)

〃客户端测试类

classMainClassextendsJFrame

(

privateJButtonbutton;

privateJDesktopPanedesktopPane;

privateSubFrameiFrame=null;

publicMainClass()

(

super("主窗体)

Containerc=this.getContentPane();

c.setLayout(newBorderLayoutO);

button=newJButton("点击创建一个内部窗体)

button.addActionListener(newBtListener());

c.add(button,BorderLayout.SOUTH);

desktopPane=newJDesktopPane。;〃仓犍DesktopPane

c.add(desktopPane);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setLocationRelativeTo(null);

this.setSize(400,400);

this.show();

)

//事件监听器

classBtListenerimplementsActionListener

(

publicvoidactionPerformed(ActionEvente)

18

if(iFrame!=null)

(

desktopPane.remove(iFrame);

)

iFrame=SubFrame.getFrame();

desktopPane.add(iFrame);

)

)

publicstaticvoidmain(Stringf]args)

(

newMainClass();

)

)

其中,SubFrame类是JlnternalFrame类的子类,在SubFrame类中定义了一个静态的

SubFrame类型的实例变量,在静态工厂方法getFrame()中创建了SubFrame对象并将其返回。

在MainClass类中使用了该单例类,确保子窗口在当前应用程序中只有唯一一个实例,即只能

弹出一个子窗口。

8.参考类图如下所示:

Multiton

-array:Multiton[]

-Multiton()

+getlnstance():Multiton

+random():int

多例模式(MultitonPattern)是单例模式的一种扩展形式,多例类可以有多个实例,而且

必须自行创建和管理实例,并向外界提供自己的实例,可以通过静态集合对象来存储这些实例。

多例类Multiton的代码如下所示:

importjava.util.*;

publicclassMultiton

(

〃定义一个数组用于存储四个实例

privatestaticMultiton[]array={newMultiton(),newMultiton(),newMultiton(),new

Multiton()};

〃私有构造函数

privateMultiton()

(

)

〃静态工厂方法,随机返回数组中的一个实例

publicstaticMultitongetlnstance()

(

returnarray[random()];

〃随机生成一个整数作为数组下标

19

publicstaticintrandom()

{

Dated=newDate();

Randomrandom=newRandom();

intvalue=Math.abs(random.nextlnt());

value=value%4;

returnvalue;

)

publicstaticvoidmain(Stringargs[])

(

Multitonml,m2,m3,m4;

ml=Multiton.getlnstance();

m2=Multiton.getlnstanceO;

m3=Multiton.getlnstance();

m4=Multiton.getlnstanceO;

System.out.println(m1==m2);

System.out.println(m1==m3);

System.out.println(m1==m4);

第9章适配器模式

1.B

2.C

3.A

4.A

5.在对象适配器中,适配器与适配者之间是关联关系,一个适配器能够对应多个适配者类,

只需要在该适配器类中定义对多个适配者对象的引用即可;在类适配器中,适配器与适配者是

继承关系,一个适配器能否适配多个适配者类取决于该编程语言是否支持多重类继承,例如

C++语言支持多重类继承则可以适配多个适配者,而Java、C#等语言不支持多重类继承则不

能适配多个适配者。

6.参考类图如下所示:

20

其中,Adapter充当适配器,Cat和Dog既充当抽象目标,又充当抽象适配者。如果客

户端针对Cat编程,则Cat充当抽象目标,Dog充当抽象适配者,ConcreteDog充当具体适

配者;如果客户端针对Dog编程,则Dog充当抽象目标,Cat充当抽象适配者,ConcreteCat

充当具体适配者。在此使用对象适配器,Adapter类的代码如下所示:

classAdapterimplementsCat,Dog

(

privateCatcat;

privateDogdog;

publicvoidsetCat(Catcat)

(

this.cat=cat;

)

publicvoidsetDog(Dogdog)

(

this.dog=dog;

)

publicvoidcry()〃猫学狗叫

(

dog.wangO;

)

publicvoidcatchMouse()

(

cat.catchMouse();

)

publicvoidwang()

(

dog.wangO;

)

publicvoidaction()〃狗学猫抓老鼠

21

cat.catchMouse();

RealPlayerFactory,其中MediaPlayerFactory作为WindowsMediaPlayer播放器工厂,可以创

建WindowsMediaPlayer的主窗口(MediaPlayerWindow)和播放列表(MediaPlayerList)(为了

简化类图,只列出主窗口和播放列表这两个播放器组成元素,实际情况下包含更多组成元

素);RealPlayerFactory作为RealPlayer播放器工厂,创建RealPlayer的主窗口

(RealPlayerWindow)和播放列表(RealPlayerList),此时可以使用抽象工厂模式,客户

端针对抽象工厂PlayerFactory编程,如果增加新的播放器,只需增加一个新的具体工厂来

生产新产品族中的产品即可。由于需要调用现有API中的方法,因此还需要使用适配器模式,

在具体产品类如MediaPlayerWindow和MediaPlayerList调用WindowsMediaPlayerAPI中的

方法,在RealPlayerWindow和RealPlayerList中调用RealPlayerAPI中的方法,实现对API

中方法的适配,此时具体产品如MediaPlayerWindowRealPlayerWindow等充当适配器,而

已有的API如MediaPlayerAPI和RealPlayerAPI是需要适配的适配者。

8.参考类图(对象适配器)如下所示:

22

其中,DataOperator充当目标抽象类角色,CipherAdapter和NewCipherAdapter充当适

配器角色,Caesar和NewCipher充当适配者角色。

类适配器设计方案只需将上图中适配器与适配者之间的关联关系改为继承关系即可。

第10章桥接模式

1.BD

2.C

3.C

4.桥接模式可以处理存在多个独立变化维度的系统,每一个独立维度对应一个继承结构,

其中一个为“抽象类''层次结构,其他为“实现类''层次结构,"抽象类''层次结构中的抽象类与

"实现类''层次结构中的接口之间存在抽象耦合关系。

5.参考类图如下所示:

其中,Manufacturer充当抽象类角色,Airbus、Boeing和MD充当扩充抽象类角色,Plane

充当实现类接口角色,PassengerPlane和CargoPlane充当具体实现类角色。

6.参考类图如下所示:

23

其中,FileConvertor充当抽象类角色,TXTConvertor、XMLConvertor和PDFConvertor

充当扩充抽象类角色,DataHandler充当实现类接口角色,OracleHandler和SQLServerHandler

充当具体实现类角色。

第11章组合模式

1.B

2.B

3.C

4.结果:容器(Composite)对象中只能包含叶子(Leaf)对象,不能再继续包含容器对象,导致

无法递归构造出一个多层树形结构。

5.参考类图如下所示:

本题使用了安全组合模式,Unil充当抽象构件角色,Office充当叶子构件角色,Institution

充当容器构件角色。

6.参考类图如下所示:

Component

24

其中,Component充当抽象构件角色,Button和Textbox充当叶子构件角色,Container

充当抽象容器构件角色,Form和Panel充当具体容器构件角色。

第12章装饰模式

1.D

2.C

3.不能实现对用一个对象的多次装饰。因为在半透明装饰模式中,使用具体装饰类来声明

装饰之后的对象,具体装饰类中新增的方法并未在抽象构件类中声明,这样做的优点在于装饰

后客户端可以单独调用在具体装饰类中新增的业务方法,但是将导致无法调用到之前装饰时新

增的方法,只能调用到最后一次装饰时具体装饰类中新增加的方法,故对同一个对象实施多次

装饰没有任何意义。

4.参考类图如下所示:

其中,Cellphone为抽象类,声明了来电方法receiveCall。,SimplePhone为简单手机类,

提供了声音提示,JarPhone和ComplexPhone分别提供了振动提示和灯光闪烁提示。

PhoneDecorator是抽象装饰者,它维持一个对父类对象的引用。

5.参考类图如下所示:

其中,Beverage充当抽象组件,HouseBlend和Espresso充当具体组件,

ChxfoEDeooufcr充当抽象装饰器,Milk和Mocha充当具体装饰器,StarBuzzCoffee充当客户

端。本题完整代码示例如下所示:

25

abstractclassBeverage//抽象组件

(

publicabstractStringgetDescription();

publicabstractdoublegetCost();

)

classHouseBlendextendsBeverage〃具体组件

(

publicStringgetDescription()

(

return''HouseBlend咖啡”;

)

publicdoublegetCost()

(

return10.00;

)

)

classEspressoextendsBeverage〃具体组件

(

publicStringgetDescription()

(

return"Espresso咖啡”;

)

publicdoublegetCost()

(

return20.00;

)

)

classCondimentDecoratorextendsBeverage〃抽象装饰器

(

privateBeveragebeverage;

publicCondimentDecorator(Beveragebeverage)

(

this.beverage=beverage;

)

publicStringgetDescription()

(

returnbeverage.getDescription();

)

publicdoublegetCost()

returnbeverage.getCost();

26

classMilkextendsCondimentDecorator//具体装饰器

(

publicMiIk(Beveragebeverage)

(

super(beverage);

)

publicStringgetDescription()

(

Stringdecription=super.getDescription();

returndecription+”加牛奶”;

)

publicdoublegetCost()

(

doublecost=super.getCost();

returncost+2.0;

)

)

classMochaextendsCondimentDecorator〃具体装饰器

(

publicMocha(Beveragebeverage)

(

super(beverage);

)

publicStringgetDescription()

(

Stringdecription=super.getDescription();

returndecription+”加摩卡”;

)

publicdoublegetCost()

(

doublecost=super.getCost();

returncost+3.0;

classStarBuzzCoffee//客户端测试类

(

publicstaticvoidmain(Stringargs[])

Stringdecription;

27

doublecost;

Beveragebeverage_e;

beverage_e=newEspresso();

decription=beverage_e.getDescription();

cost=beverage_e.getCost();

System.oul.println("饮料:"+decription);

System.out.println(H价格:"+cost);

System.out.println("--------------------");

Beveragebeverage_mi;

beverage_mi=newMilk(beverage_e);

decription=beverage_mi.getDescription();

cost=beverage_mi.getCost();

System.oul.println("饮料:"+decription);

System.out.printin(“价格:"+cost);

System.out.println(n--------------------");

Beveragebeverage_mo;

beverage_mo=newMocha(beverage_mi);

decription=beverage_mo.getDescription();

cost=beverage_mo.getCost();

System.out.println(“饮料:"+decription);

System.out.println(M价格:"+cost);

System.out.println("--

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论