第4章 结构型模式实训

更新时间:2024-04-24 20:09:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第4章 结构型模式实训

4.3 实训练习

4.3.1 选择题

1. 某公司开发一个文档编辑器,该编辑器允许在文档中直接嵌入图形对象,但开销很大。用户在系统设计之初提出编辑器在打开文档时必须十分迅速,可以暂时通过一些符号来表示相应的图形。针对这种需求,公司可以采用( )避免同时创建这些图形对象。

A. 代理模式 B. 外观模式 C. 桥接模式 D. 组合模式

2. 下面的( )模式将对象组合成树形结构以表示“部分-整体”的层次结构,并使得用户对单个对象和组合对象的使用具有一致性。

A. 组合 (Composite) B. 桥接 (Bridge) C. 装饰 (Decorator) D. 外观 (Facade)

3. 已知某子系统为外界提供功能服务,但该子系统中存在很多粒度十分小的类,不便被外界系统直接使用,采用( )设计模式可以定义一个高层接口,这个接口使得这一子系统更加容易使用。

A. Facade(外观) B. Singleton(单例) C. Participant(参与者) D. Decorator(装饰)

4. 当不能采用生成子类的方法进行扩充时,可采用( )设计模式动态地给一个对象添加一些额外的职责。

A. Facade(外观) B. Singleton(单例) C. Participant(参与者) D. Decorator(装饰)

5. ( ① )设计模式将抽象部分与它的实现部分相分离,使它们都可以独立地变化。下图为该设计模式的类图,其中,( ② )用于定义实现部分的接口。

Abstraction+operation ()...implImplementor+operationImpl ()...impl.operationImpl();RefinedAbstractionConcreteImplementorAConcreteImplementorB+operation ()+operationImpl ()+operationImpl () .........① A. Singleton(单例) B. Bridge(桥接) C. Composite(组合) D. Facade(外观)

② A. Abstraction B. ConcreteImplementorA C. ConcreteImplementorB D. Implementor

6. ( ① )限制了创建类的实例数量,而( ② )将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

① A. 命令模式 (Command) B. 适配器模式 (Adapter)

C. 策略模式 (Strategy) D. 单例模式 (Singleton) ② A. 命令模式 (Command) B. 适配器模式 (Adapter) C. 策略模式 (Strategy) D. 单例模式 (Singleton) 7. 一个树形文件系统体现了( )模式。

A. Decorator(装饰) B. Composite(组合) C. Bridge(桥接) D. Proxy(代理)

8. 当应用程序由于使用大量的对象,造成很大的存储开销时,可以采用( )设计模式运用共享技术来有效地支持大量细粒度对象的重用。

A. Facade(外观) B. Composite(组合) C. Flyweight(享元) D. Adapter(适配器)

9. 当想使用一个已经存在的类,但其接口不符合需求时,可以采用( )设计模式将该类的接口转换成我们希望的接口。

A. 命令 (Command) B. 适配器 (Adapter)

C. 装饰 (Decorator) D. 享元 (Flyweight) 10. 以下关于适配器模式的叙述错误的是( )。

A. 适配器模式将一个接口转换成客户希望的另一个接口,使得原本接口不兼容的那些类可以一起工作 B. 在类适配器中,Adapter和Adaptee是继承关系,而在对象适配器中,Adapter和Adaptee是关联关系 C. 类适配器比对象适配器更加灵活,在Java、C#等语言中可以通过类适配器一次适配多个适配者类 D. 适配器可以在不修改原来的适配者接口Adaptee的情况下将一个类的接口和另一个类的接口匹配起来

11. 现需要开发一个文件转换软件,将文件由一种格式转换为另一种格式,如将XML文件转换为PDF文件,将DOC文件转换为TXT文件,有些文件格式转换代码已经存在,为了将已有的代码应用于新软件,而不需要修改软件的整体结构,可以使用( )设计模式进行系统设计。 A. 适配器 (Adapter) B. 组合 (Composite) C. 外观 (Facade) D. 桥接 (Bridge)

12. 在对象适配器中,适配器类(Adapter)和适配者类(Adaptee)之间的关系为( )。 A. 关联关系 B. 依赖关系 C. 继承关系 D. 实现关系 13. ( )是适配器模式的应用实例。

A. 操作系统中的树形目录结构 B. Windows中的应用程序快捷方式 C. Java事件处理中的监听器接口 D. JDBC中的数据库驱动程序

14. 以下陈述不属于桥接模式优点的是( )。

A. 分离接口及其实现部分,可以独立地扩展抽象和实现

B. 可以使原本由于接口不兼容而不能一起工作的那些类一起工作 C. 可以取代多继承方案,比多继承方案扩展性更好

D. 符合开闭原则,增加新的细化抽象和具体实现都很方便 15. 以下关于桥接模式的叙述错误的是( )。

A. 桥接模式的用意是将抽象化与实现化脱耦,使得两者可以独立地变化 B. 桥接模式将继承关系转换成关联关系,从而降低系统的耦合度

C. 桥接模式可以动态地给一个对象增加功能,这些功能也可以动态地撤销 D. 桥接模式可以从接口中分离实现功能,使得设计更具扩展性 16. ( )不是桥接模式所适用的场景。

A. 一个可以跨平台并支持多种格式的文件编辑器

B. 一个支持多数据源的报表生成工具,可以以不同图形方式显示报表信息

C. 一个可动态选择排序算法的数据操作工具 D. 一个支持多种编程语言的跨平台开发工具 17. 以下关于组合模式的叙述错误的是( )。

A. 组合模式对叶子对象和组合对象的使用具有一致性

B. 组合模式可以通过类型系统来对容器中的构件实施约束,可以很方便地保证在一个容器中只能有某些特定的构件

C. 组合模式将对象组织到树形结构中,可以用来描述整体与部分的关系

D. 组合模式使得可以很方便地在组合体中加入新的对象构件,客户端不需要因为加入新的对象构件而更改代码

18. 下图是( )模式的结构图。 ComponentClient++++operation ()add (Component c)remove (Component c)getChild (int i)...Leaf+operation ()...++++Compositeoperation ()add (Component c)remove (Component c)getChild (int i)...children A. 模板方法 B. 命令 C. 单例 D. 组合 19. 现需要开发一个XML文档处理软件,可以根据关键字查询指定内容,用户可以在XML中任意选取某一节点为查询的初始节点,无须关心该节点所处的层次结构。针对该需求,可以使用( )模式来进行设计。

A. Abstract Factory(抽象工厂) B. Flyweight(享元) C. Composite(组合) D. Strategy(策略)

20. 某公司欲开发一个图形控件库,要求可以在该图形控件库中方便地增加新的控件,而且可以动态地改变控件的外观或给控件增加新的行为,如可以为控件增加复杂的立体边框、增加控件的鼠标拖拽行为等。针对上述需求,使用( )模式来进行设计最合适。

A. 适配器 (Adapter) B. 装饰 (Decorator) C. 外观 (Facade) D. 命令 (Command) 21. 以下( )不是装饰模式的适用条件。

A. 要扩展一个类的功能或给一个类增加附加责任

B. 要动态地给一个对象增加功能,这些功能还可以动态撤销 C. 要动态组合多于一个的抽象化角色和实现化角色

D. 要通过一些基本功能的组合而产生复杂功能,而不使用继承关系

22. Java IO库的设计使用了装饰模式,局部类图如下所示,在该类图中,类( ① )充当具体构件ConcreteComponent,类( ② )充当抽象装饰器Decorator,类( ③ )充当具体装饰器ConcreteDecorator。

OutputStreamFileOutputStreamFilterOutputStream-out: OutputStreamoutBufferedOutputStreamDataOutputStream

① A. OutputStream B. FileOutputStream C. FilterOutputStream D. BufferedOutputStream ② A. OutputStream B. FileOutputStream C. FilterOutputStream D. BufferedOutputStream ③ A. OutputStream B. FileOutputStream C. FilterOutputStream D. BufferedOutputStream 23. 下图是( )模式的类图。

MainFrameSubSystemASubSystemB

A. 桥接 (Bridge) B. 工厂方法 (Factory Method) C. 模板方法 (Template Method) D. 外观 (Facade) 24. 以下关于外观模式的叙述错误的是( )。

A. 外观模式要求一个子系统的外部与其内部的通信必须通过一个统一的外观对象进行

B. 在增加外观对象之后,客户类只需要直接和外观对象交互即可,子系统类间的复杂关系由外观类来实现,降低了系统的耦合度

C. 外观模式可以很好地限制客户使用子系统类,对客户访问子系统类做限制可以提高系统的灵活性 D. 如果一个系统有好几个子系统的话,可以提供多个外观类

25. 在享元模式中,外部状态是指( )。 A. 享元对象可共享的所有状态 B. 享元对象可共享的部分状态 C. 由享元对象自己保存和维护的状态

D. 由客户端保存和维护的状态

26. 以下关于享元模式的叙述错误的是( )。

A. 享元模式运用共享技术有效地支持大量细粒度对象的复用

B. 在享元模式中可以多次使用某个对象,通过引入外部状态使得这些对象可以有所差异

C. 享元对象能够做到共享的关键是引入了享元池,在享元池中通过克隆方法向客户端返回所需对象 D. 在享元模式中,外部状态是随环境改变而改变、不可以共享的状态,而内部状态是不随环境改变而改变、可以共享的状态

27. 为了节约系统资源,提高程序的运行效率,某系统在实现数据库连接池时可以使用( )设计模式。

A. 外观(Facade) B. 原型(Prototype) C. 代理(Proxy) D. 享元(Flyweight)

28. 毕业生通过职业介绍所找工作,该过程蕴含了( )模式。

A. 外观(Facade) B. 命令(Command) C. 代理(Proxy) D. 桥接(Bridge) 29. 代理模式有多种类型,其中智能引用代理是指( )。

A. 为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果 B. 保护目标不让恶意用户接近

C. 使几个用户能够同时使用一个对象而没有冲突

D. 当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来 30. 以下关于代理模式的叙述错误的是( )。

A. 代理模式能够协调调用者和被调用者,从而在一定程序上降低系统的耦合度

B. 控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限时可以考虑使用远程代理 C. 代理模式的缺点是请求的处理速度会变慢,并且实现代理模式需要额外的工作 D. 代理模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用

4.3.2 填空题

1. 某公司欲开发一款儿童玩具汽车,为了更好地吸引小朋友的注意力,该玩具汽车在移动过程中伴随着灯光闪烁和声音提示,在该公司以往的产品中已经实现了控制灯光闪烁和声音提示的程序,为了重用先前的代码并且使得汽车控制软件具有更好的灵活性和扩展性,使用适配器模式设计该系统,所得类图如图1所示。

CarController{abstract} +move ()+sound ()+light ()...CarAdapter-sound: Sound-lamp: Lamp+CarAdapter ()+sound ()+light ()...ClientConcreteSound+phonate ()...Sound{abstract} +phonate ()...图1 类图

Lamp{abstract} +twinkle ()...ConcreteLamp+twinkle ()... 在图1中,CarController类是汽车控制器,它包括三个方法用于控制汽车的行为,其中move()用于控制汽车的移动,sound()用于控制汽车的声音,light()用于控制汽车灯光的闪烁, sound()和light()是抽象方法。Sound类是抽象声音类,其方法phonate()用于实现声音提示,在其子类ConcreteSound中实现了该方法;Lamp类是灯光类,其方法twinkle()用于实现灯光闪烁,在其子类ConcreteLamp中实现了该方法。CarAdapter充当适配器,它通过分别调用Sound类的phonate()方法和Lamp类的twinkle()方法实现声音播放和灯光闪烁。 【Java代码】

abstract class Sound //抽象声音类 { public abstract void phonate(); } class ConcreteSound extends Sound //具体声音类 { public void phonate() { System.out.println(\声音播放!\ } } abstract class Lamp //抽象灯光类 { public abstract void twinkle(); } class ConcreteLamp extends Lamp //具体灯光类 { public void twinkle() { System.out.println(\灯光闪烁!\ } } (1) CarController //汽车控制器 { public void move() { System.out.println(\汽车移动!\ } public abstract void sound(); public abstract void light(); } class CarAdapter (2) //汽车适配器 { private Sound sound; private Lamp lamp; public CarAdapter(Sound sound,Lamp lamp) { (3) ; (4) ; } public void sound() { (5) ; //声音播放 } public void light() { (6) ; //灯光闪烁 } } class Client { public static void main(String args[]) { Sound sound; Lamp lamp; CarController car; sound = new ConcreteSound(); lamp = new ConcreteLamp(); car = (7) ; car.move(); car.sound(); car.light(); } } 在本实例中,使用了 (8) (填写类适配器或对象适配器)模式。

2. 现欲实现一个图像浏览系统,要求该系统能够显示BMP、JPEG和GIF三种格式的文件,并且能够在Windows和Linux两种操作系统上运行。系统首先将BMP、JPEG和GIF三种格式的文件解析为像素矩阵,然后将像素矩阵显示在屏幕上。系统需具有较好的扩展性以支持新的文件格式和操作系统。为满足上述需求并减少所需生成的子类数目,采用桥接设计模式进行设计所得类图如图1所示。

ImageImageImp+setImp ()+parseFile ()...+doPaint ()...BMPGIFJPEGWinImpLinuxImp 图1 类图

采用该设计模式的原因在于:系统解析BMP、JPEG与GIF文件的代码仅与文件格式相关,而在屏幕上显示像素矩阵的代码则仅与操作系统相关。 【Java代码】 class Matrix { //各种格式的文件最终都被转化为像素矩阵 //此处代码省略 } interface ImageImp { public void doPaint(Matrix m); //显示像素矩阵m } class WinImp implements ImageImp { public void doPaint(Matrix m) {/*调用Windows系统的绘制函数绘制像素矩阵*/} } class LinuxImp implements ImageImp { public void doPaint(Matrix m) {/*调用Linux系统的绘制函数绘制像素矩阵*/} } abstract class Image { public void setImp(ImageImp imp) { (1) = imp; } public abstract void parseFile(String fileName); protected (2) imp; } class BMP extends Image { public void parseFile(String fileName) { //此处解析BMP文件并获得一个像素矩阵对象m (3) ;//显示像素矩阵m } } class GIF extends Image { //此处代码省略 } class JPEG extends Image { //此处代码省略 } public class Main{ public static void main(String[] args) { //在Windows操作系统上查看demo.bmp图像文件 Image image1 = (4) ; ImageImp imageImp1 = (5) ; (6) ; image1.parseFile(\ } } 现假设该系统需要支持10种格式的图像文件和5种操作系统,不考虑类Matrix和类Main,若采用桥接模式则至少需要设计 (7) 个类。

3. 某公司的组织结构图如图1所示,现采用组合设计模式来设计,得到如图2所示的类图。

北京公司总部总公司人力资源部上海分公司总公司财务部南京办事处上海分公司人力资源部上海分公司财务部南京办事处人力资源部南京办事处财务部图1 组织结构图

Company+Add (Company c): void+Delete (Company c): void...FinanceDepartment+Add (Company c): void+Delete (Company c): void...HRDepartment+Add (Company c): void+Delete (Company c): void...图2 类图

ConcreteCompany+Add (Company c): void+Delete (Company c): void ...其中Company 为抽象类,定义了在组织结构图上添加(Add)和删除(Delete)分公司/办事处或者部门的方法接口。类ConcreteCompany表示具体的分公司或者办事处,分公司或办事处下可以设置不同的部门。类HRDepartment和FinanceDepartment 分别表示人力资源部和财务部。 【Java代码】 import java.util.*; (1) Company { protected String name; public Company(String name) { (2) = name; } public abstract void Add(Company c); // 增加子公司、办事处或部门 public abstract void Delete(Company c); // 删除子公司、办事处或部门 } class ConcreteCompany extends Company { private List< (3) > children = new ArrayList< (4) >(); // 存储子公司、办事处或部门 public ConcreteCompany(String name) { super(name); } public void Add(Company c) { (5) .add(c); } public void Delete(Company c) { (6) .remove(c); } } class HRDepartment extends Company { public HRDepartment(String name) { super(name); } // 其他代码省略 } class FinanceDepartment extends Company { public FinanceDepartment(String name) { super(name); } // 其他代码省略 } public class Test { public static void main(String[] args) { ConcreteCompany root = new ConcreteCompany(\北京总公司\root.Add(new HRDepartment(\总公司人力资源部\root.Add(new FinanceDepartment(\总公司财务部\ConcreteCompany comp = new ConcreteCompany(\上海分公司\comp.Add(new HRDepartment(\上海分公司人力资源部\comp.Add(new FinanceDepartment(\上海分公司财务部\ (7) ; ConcreteCompany comp1 = new ConcreteCompany(\南京办事处\comp1.Add(new HRDepartment(\南京办事处人力资源部\comp1.Add(new FinanceDepartment(\南京办事处财务部\ (8) ; // 其他代码省略 } } 4. 某公司欲开发一套手机来电提示程序,在最简单的版本中,手机在接收到来电时会发出声音来提醒用户;在振动版本中,除了声音外,在来电时手机还能产生振动;在更高级的版本中手机不仅能够发声和产生振动,而且还会有灯光闪烁提示。现采用装饰设计模式来设计,得到如图1所示的类图。

Cellphone+receiveCall (): void...SimplePhone+receiveCall (): void...PhoneDecorator-phone: Cellphone+PhoneDecorator (Cellphone phone)+receiveCall (): void...phoneJarPhoneComplexPhone+JarPhone (Cellphone phone)+ComplexPhone (Cellphone phone)+receiveCall (): void+receiveCall (): void ......图1 类图

其中Cellphone为抽象类,声明了来电方法receiveCall(),SimplePhone为简单手机类,提供了声音提示,JarPhone和ComplexPhone分别提供了振动提示和灯光闪烁提示。PhoneDecorator是抽象装饰者,它维持一个对父类对象的引用。 【Java代码】 abstract class Cellphone { public abstract void receiveCall(); } class SimplePhone extends Cellphone { public void receiveCall() { System.out.println(\声音提示\ } } class PhoneDecorator extends Cellphone { private (1) phone=null; public PhoneDecorator(Cellphone phone) { if(phone!=null) { (2) ; } else { this.phone=new SimplePhone(); } } public void receiveCall() { (3) ; } } class JarPhone extends PhoneDecorator { public JarPhone(Cellphone phone) { (4) ; } public void receiveCall() { super.receiveCall(); System.out.println(\振动提示\ } } class ComplexPhone extends PhoneDecorator { public ComplexPhone(Cellphone phone) { (5) ; } public void receiveCall() { super.receiveCall(); System.out.println(\灯光闪烁提示\ } } class Client { public static void main(String a[]) { Cellphone p1=new (6) ; //创建具有声音提示的手机 p1.receiveCall(); Cellphone p2=new (7) ; //创建具有声音提示和振动提示的手机 p2.receiveCall(); Cellphone p3=new (8) ; //创建具有声音提示、振动提示和灯光提示的手机 p3.receiveCall(); } } 5. 某信息系统需要提供一个数据读取和报表显示模块,可以将来自不同类型文件中的数据转换成XML格式,并对数据进行统计和分析,然后以报表方式来显示数据。由于该过程需要涉及到多个类,因此使用外观模式进行设计,其类图如图1所示:

AbstractFacade{abstract} +execute ()...XMLFacade+execute ()...ExtendedFacade+execute ()...FileOperation+read ()...XMLDataConvertor+convert ()...DataAnalysis+handle ()...ReportDisplay+display ()... 图1 类图

在图1中,FileOperation类用于读取文件、XMLDataConvertor类用于将不同格式的文件转换为XML格式、DataAnalysis类用于对XML数据进行统计分析、ReportDisplay类用于显示报表。为了让系统具有更好的扩展性,在系统设计中引入了抽象外观类AbstractFacade,它拥有多个不同的子类,如XMLFacade,它用于与读取、分析和显示XML数据的类交互,ExtendedFacade类用于与读取、转换、分析和显示非XML数据的类交互。 【Java代码】

class FileOperation { public String read(String fileName) { //读取文件代码省略 } } class XMLDataConvertor { public String convert(String fileStr) { //文件格式转换代码省略 } } class DataAnalysis { public String handle(String xmlStr) { //数据分析统计代码省略 } } class ReportDisplay { public void display(String xmlStr) { //报表显示代码省略 } } (1) AbstractFacade { public abstract void execute(String fileName); } class XMLFacade extends AbstractFacade { private FileOperation fo; private DataAnalysis da; private ReportDisplay rd; public XMLFacade() { fo = new FileOperation(); da = new DataAnalysis(); rd = new ReportDisplay(); } public void execute(String fileName) { String str = (2) ; //读取文件 String strResult = (3) ; //分析数据 (4) ; //显示报表 } } class ExtendedFacade extends AbstractFacade { private FileOperation fo; private XMLDataConvertor dc; private DataAnalysis da; private ReportDisplay rd; public ExtendedFacade() { fo = new FileOperation(); dc = new XMLDataConvertor(); da = new DataAnalysis(); rd = new ReportDisplay(); } public void execute(String fileName) { String str = (5) ; //读取文件 String strXml = (6) ; //转换文件 String strResult = (7) ; //分析数据 (8) ; //显示报表 } } class Test { public static void main(String args[]) { AbstractFacade facade; facade = (9) ; facade.execute(\ } } 6. 某软件公司欲开发一个多功能文本编辑器,在文本中可以插入图片、动画、视频等多媒体资料,为了节约系统资源,使用享元模式设计该系统,所得类图如图1所示:

Location-x: int-y: int+Location (int x, int y)+getX ()+setX (int x)+getY ()+setY (int y)...Size-width: int-height: int+Size (int width, int height)+getWidth ()+setWidth (int width)+getHeight ()+setHeight (int height)...: int: void: int: void: int: void: int: voidMultimediaFileFactory-ht: Hashtable-fileNum: int = 0+MultimediaFileFactory ()+getMultimediaFile (String fileName): MultimediaFile+getFileNum (): int...MultimediaFile{abstract} ##+++size: Sizelocation: Locationdisplay (): voidsetSize (Size size): voidsetLocation (Location location): void...ImageAnimationVideo 图1 类图

在图1中,MultimediaFile表示抽象享元,其子类Image、Animation和Video表示具体享元。对于相同的多媒体文件,其大小Size和位置Location可以不同,因此需要通过Setter方法来设置这些外部状态。MultimediaFileFactory是享元工厂,在其中定义一个Hashtable对象作为享元池,存储和维护享元对象。 【Java代码】

import java.util.*; //位置类:外部状态类 class Location { private int x; private int y; public Location(int x,int y) { this.x = x; this.y = y; } //Getter方法和Setter方法省略 } //大小类:外部状态类 class Size { private int width; private int height; public Size(int width,int height) { this.width = width; this.height = height;

} //Getter方法和Setter方法省略 } //多媒体文件类:抽象享元类 (1) MultimediaFile { protected Size size; protected Location location; public abstract void display(); public void setSize(Size size) { this.size = size; } public void setLocation(Location location) { this.location = location; } } //图片文件类:具体享元类 class Image extends MultimediaFile { private String fileName; public Image(String fileName) { this.fileName = fileName; } public void display() { //导入和显示图片文件代码省略,在显示图片时将使用size和location对象 } } //动画文件类:具体享元类 class Animation extends MultimediaFile { //动画文件类代码省略 } //视频文件类:具体享元类 class Video extends MultimediaFile { //视频文件类代码省略 } //多媒体文件工厂类:享元工厂类 class MultimediaFileFactory { private Hashtable ht; //享元池 private int fileNum = 0; //享元对象计数器 public MultimediaFileFactory() { ht = (2) ; } //从享元池中获取对象 public (3) getMultimediaFile(String fileName) { //根据文件后缀名判断文件类型 String[] strArray = fileName.split(\ int ubound = strArray.length; String extendName = strArray[ubound-1]; if(ht.containsKey(fileName)) { return (MultimediaFile) (4) ; } else { if(extendName.equalsIgnoreCase(\ { MultimediaFile file = new Image(fileName); ht.put(fileName,file); fileNum++; } else if(extendName.equalsIgnoreCase(\ { MultimediaFile file = new Animation(fileName); ht.put(fileName,file); (5) ; } //其他代码省略 } } //返回享元对象数量 public int getFileNum() { return fileNum; } } class Test { public static void main(String args[]) { MultimediaFile file1,file2,file3,file4; MultimediaFileFactory factory; factory = new MultimediaFileFactory(); file1 = factory.getMultimediaFile(\ file1.setSize(new Size(300,400)); } } file1.setLocation(new Location(3,5)); file2 = factory.getMultimediaFile(\file2.setSize(new Size(300,400)); file2.setLocation(new Location(6,5)); file3 = factory.getMultimediaFile(\file3.setSize(new Size(200,200)); file3.setLocation(new Location(10,1)); file4 = factory.getMultimediaFile(\file4.setSize(new Size(400,400)); file4.setLocation(new Location(15,2)); System.out.println(file1==file2); //输出语句1 System.out.println(factory.getFileNum()); //输出语句2 在Test类中,“输出语句1”输出结果为 (6) ,“输出语句2”输出结果为 (7) 。

7. 某信息咨询公司推出收费的在线商业信息查询模块,需要对查询用户进行身份验证并记录查询日志,以便根据查询次数收取查询费用,现使用代理模式设计该系统,所得类图如图1所示:

Searcher+doSearch (): String...ProxySearcher-searcher: RealSearcher-validator: AccessValidator-logger: Logger+doSearch (): String+validate (): boolean+log (): void...AccessValidator+validate (): boolean...Logger+log (): void...图1 类图

RealSearcher+doSearch (): String... 在图1中,AccessValidator类用于验证用户身份,它提供方法validate()来实现身份验证;Logger类用于记录用户查询日志,它提供方法log()来保存日志;RealSearcher类实现查询功能,它提供方法doSearch()来查询信息。ProxySearcher作为查询代理,维持对RealSearcher对象、AccessValidator对象和Logger对象的引用。 【Java代码】 class AccessValidator { public boolean validate(String userId) { //身份验证实现代码省略 } } class Logger { public void log(String userId) { //日志记录实现代码省略 } } interface Searcher { public String doSearch(String userId,String keyword); } class RealSearcher implements Searcher { public String doSearch(String userId,String keyword) { //信息查询实现代码省略 } } class ProxySearcher (1) { private RealSearcher searcher = new RealSearcher(); private AccessValidator validator; private Logger logger; public String doSearch(String userId,String keyword) { //如果身份验证成功,则执行查询 if( (2) ) { String result = searcher.doSearch(userId,keyword); (3) ; //记录查询日志 (4) ; //返回查询结果 } else { return null; } } public boolean validate(String userId) { validator = new AccessValidator(); (5) ; } public void log(String userId) { logger = new Logger(); (6) ; } } class Test { public static void main(String args[]) { (7) ; //针对抽象编程,客户端无须分辨真实主题类和代理类 searcher = new ProxySearcher(); String result = searcher.doSearch(\ //此处省略后续处理代码 } } 4.3.3 综合题

1. 实现一个双向适配器实例,使得猫(Cat)可以学狗(Dog)叫,狗可以学猫抓老鼠。绘制相应类图并使用代码编程模拟。

2. 海尔(Haier)、TCL、海信(Hisense)都是家电制造商,它们都生产电视机(Television)、空调(Air Conditioner)、冰箱(Refrigeratory)。现需要设计一个系统,描述这些家电制造商以及它们所制造的电器,要求绘制类图并用代码模拟实现。

3. 某教育机构组织结构如下图所示:

北京总部教务办公室湖南分校行政办公室教务办公室长沙教学点湘潭教学点行政办公室教务办公室行政办公室教务办公室行政办公室

在该教育机构的OA系统中可以给各级办公室下发公文,现采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。

4. 某系统中的文本显示组件类(TextView)和图片显示组件类(PictureView)都继承了组件类(Component),分别用于显示文本内容和图片内容,现需要构造带有滚动条、或者带有黑色边框、或者既有滚动条又有黑色边框的文本显示组件和图片显示组件,为了减少类的个数可使用装饰模式进行设计,绘制类图并编程模拟实现。

5. 在电脑主机(Mainframe)中,只需要按下主机的开机按钮(on()),即可调用其他硬件设备和软件的启动方法,如内存(Memory)的自检(check()),CPU的运行(run()),硬盘(HardDisk)的读取(read()),操作系统(OS)的载入(load())等,如果某一过程发生错误则电脑启动失败。使用外观模式模拟该过程,绘制类图并编程模拟实现。

6. 在屏幕中显示一个文本文档,其中相同的字符串“Java”共享同一个对象,而这些字符串的颜色和大小可以不同。现使用享元模式设计一个方案实现字符串对象的共享,要求绘制类图并编程实现。

7. 应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法。使用代理模式模拟该过程,绘制类图并编程模拟实现。

本文来源:https://www.bwwdw.com/article/23pp.html

Top