11.简述“开—闭”原则的基本思想。请举出一个使用了软件“开—闭”原则的软件设计模式,其中何处体现了“开—闭”原则。(1)开闭原则(Open-ClosedPrinciple,OCP):软件实体应当对扩展开放,而对修改关闭,“开-闭”原则要求软件系统能够在不需要修改原有类的基础上,通过增加类达到扩展功能的目的。(2)Abstractfactory体现了这个原则,如果想增加一类新的products,只需在product类体系中增加各个products,然后在factory类体系结构中增加一个concretefactory就可以了,而不需要对现有类做任何修改,TheOpen-closedprinciple[ocp]在不改动过模块源代码的情况下扩展模块的行为。软件实体(类模块函数等)应该是可以扩展的,但是不可以修改的。2.简述依赖例转原则的基本思想。请举出一个使用了软件依赖原则的软件设计模式,其中何处体现了依赖倒转原则。(1)依赖倒置原则(DependencyInversionPrinciple,DIP)的基本思想是:①高层模块不应该依赖于低层模块,二者都应该依赖于抽象。②抽象不应该依赖于细节,细节应该依赖于抽象。(2)Templatemethod就体现了这个原则,它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中,templatemethod使得子类不改变一个算法的结构,即可重定义该算法的某些特定步骤。3.简述单一职责原则的基本思想。请举出一个使用了软件单一职责的软件设计模式,其中何处体现了单一职责原则。(1)单一职责原则(SingleResponsibilityPrinciple,SRP)的基本思想是:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。就一个类而言,应该仅有一个引起它变化的原因。一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。单一职责原则是实现高内聚、低耦合的指导方针,在很多代码重构手法中都能找到它的存在,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。(2)简单工厂模式体现了单一职责原则。使用了简单工厂模式之后,系统中类的个数增加,每一种具体的处理方式都封装到单独的类中,而且工厂类中只有简单的判断逻辑代码,不需要关心具体的业务处理过程,很好地满足了“单一职责原则”。4.软件复用可采用类的继承方式和类的聚合方式,比较两者的优缺点。(1)聚合:一个对象拥有另一个对象或对另一个对象负责,并且聚合对象和其所有者具有相同的生命周期。聚合复用的优点:a.容器类仅能通过被包含对象的接口来对其进行访问,b.黑盒复用,因为被包含的对象的内部细节对外是不可见的。c.包装性好,d.实现上的相互依赖性比较小e.每一类只专注于一项任务f.通过获取指向其它的具有相同类型的对象应用,可以在运行期间动态地定义(对象的)2组合。聚合的缺点:a.导致系统中的对象过多b.为了能够将多个不同的对象作为组合块来使用,必须仔细地对接口进行定义。(2)类继承:是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。优点:实现简单,易于扩展。缺点:a.破坏了封装性.b.白盒复用,因为父类的内部细节对于子类而言通常是可见的.c.当父类的实现更改时,子类的也不得不会随之更改.d.从父类继承来的实现将不能再运行期间进行改变.e.只能在有限的环境中使用。5.画出合成模式(Composite)的类图。举例说明一个可以应用合成模式的软件设计实例,说明其中各角色的作用。(组合模式)实例:水果盘在水果盘(Plate)中有一些水果,如苹果(Apple)、香蕉(Banana)、梨子(Pear),当然大水果盘中还可以有小水果盘,现需要对盘中的水果进行遍历(吃),当然如果对一个水果盘执行“吃”方法,实际上就是吃其中的水果。使用组合模式模拟该场景。MyElement:为组合中的对象声明接口。在该角色中可以包含所有子类共有行为的声明和实现。Apple,Banana,Pear:没有子结点的叶子结点。表示叶子节点对象Plate:容器构件。表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象childrenClientComponent++++operation()add(Componentc)remove(Componentc)getChild(inti)...Leaf+operation()...Composite++++operation()add(Componentc)remove(Componentc)getChild(inti)...for(Componentchild:children){child.operation();}listMyElement{abstract}+eat()...:voidApple+eat()...:voidPlate-list:ArrayList+++eat()add(MyElementelement)remove(MyElementelement)...:void:void:voidBanana+eat()...:voidPear+eat()...:void3构件中定义的行为。模式应用:操作系统中的目录结构是一个树形结构,因此在对文件和文件夹进行操作时可以应用组合模式,例如杀毒软件在查毒或杀毒时,既可以针对一个具体文件,也可以针对一个目录。如果是对目录查毒或杀毒,将递归处理目录中的每一个子目录和文件。6.简述桥接模式(Bridge)的基本思想,画出桥接模式的类图。举出几种能体现“高内聚,低耦合”思想的设计模式。体现“高内聚,低耦合”思想的设计模式有:桥接模式、组合模式、装饰模式、享元模式、责任链模式、命令模式、解释模式、备忘录模式、策略模式等7.画出观察者(Observer)模式的类图并简述其基本思想,如何实现当目标对象发生变化时多个观察者对象的同步更新?基本思想:定义对象间的一种一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新。协作:当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。在得到一个具体目标的改变通知后,ConcreteObserver对象可向目标对象查询信息,ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。implClientAbstraction+operation()...Implementor+operationImpl()...RefinedAbstraction+operation()...ConcreteImplementorA+operationImpl()...ConcreteImplementorB+operationImpl()...48.画出基于类和基于对象的Adapter模式类图。比较两者在使用中的差异。适配器从结构上可以分为类适配器和对象适配器。其中类适配器使用继承关系来对类进行适配,而对象适配器是使用对象引用的方法进行适配的。类适配器:可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。对象适配器:同一个适配器可以把适配者类和它的子类都适配到目标接口。适配器模式包含如下角色:•Target:目标抽象类•Adapter:适配器类•Adaptee:适配者类•Client:客户类在类适配器模式中,适配器类实现了目标抽象类接口并继承了适配者类,并在目标抽象类的实现方法中调用所继承的适配者类的方法;在对象适配器模式中,适配器类继承了目标抽象类并定义了一个适配者类的对象实例,在所继承的目标抽象类方法中调用适配者类的相应业务方法。•(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。Adapter+request()...Target+request()...Adaptee+specificRequest()...ClientspecificRequest();adapteeAdapter+request()...Adaptee+specificRequest()...Clientadaptee.specificRequest();Target+request()...59.请列举一个使用装饰模式的例子。画出你的例子的类图结构。如果不使用这种模式会出现哪些问题?变形金刚变形金刚在变形之前是一辆汽车,它可以在陆地上移动。当它变成机器人之后除了能够在陆地上移动之外,还可以说话;如果需要,它还可以变成飞机,除了在陆地上移动还可以在天空中飞翔。出现的问题:(1)当继承机制要求为每个添加的职责创建一个新的子类。这会产生许多新的类,并且会增加系统的复杂度。(2)在层次结构高层的类将有太多的特征,应用程序将为不需要的特征付出代价。10.列举两个可以使我们在程序中不必使用if…else结构的软件设计模式。使用软件设计模式是如何做到这一点的?和常规做法相比,付出的代价是什么?策略模式和状态模式。策略模式将算法封装在一个个独立的Strategy类中消除了条件语句。这就导致客户必须了解不同的Strategy。可能不得不向客户暴露具体的实现问题。状态模式将不同状态的行为分布在多个State子类中。这就增加了子类的数目,相对于单个类的实现来说不够紧凑。11.很多设计模式都是一个抽象层,再是一个具体层。谈谈你对这种结构的认识。抽象类(abstractclass)的主要目的是为它的子类定义公共接口。一个抽象类将把它的部分或全部操作的实现延迟到子类中,因此,一个抽象类不能被实例化。在抽象类中定义却没有实现的操作被称为抽象操作(abstractoperation)。非抽象类称为具体类(concreteclass)。只根据抽象类中定义的接口来操纵对象有以下两个好处:1)客户无须知道他们使用对象的特定类型,只须对象有客户所期望的接口。2)客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。这将极大地减少子系统实现之间的相互依赖关系,12.策略模式(Strategy)和状态模式(State)的类图是完全一样的,他们分别适合在什么地方使用?可以通过环境类状态的个数来决定是使用策略模式还是状态模式。策略模式的环境类自己选择一个具体策略类,具体策略类无须关心环境类;而状态模式的环境类由于外在因素需要放进一个具体状态中,以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系。使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;如果系统中某个类的某一行为存在多种实现方式,而且这些实现方6式可以互换时使用策略模式。