UML设计模式考试题
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
该模式中包含的角色及其职责
工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。
工厂类可以被外界直接调用,创建所需的产品对象。
抽象(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
简单工厂模式的特点:
简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
在这个模式中,工厂类是整个模式的关键所在。
它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。
有利于整个软件体系结构的优化。
请问什么是责任链器模式,责任链模式包含哪些角色、可以应用在哪些场景?定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
角色:处理者、具体处理者。
场景:有许多对象可以处理用户的请求,希望程序在运行期间自动确定处理用户的那个对象;希望用户不必明确指定接受者的情况下,向多个接受者一个提交请求;程序希望动态指定可处理用户请求的对象集合
设计模式六大原则-单一职责原则、开放封闭原则、依赖倒转原则、里氏代换原则、迪米特法则、合成/聚合复用原则
标签:扩展编程设计模式class测试工作
2012-07-31 09:26 1823人阅读评论(0) 收藏举报
分类:OO(1)
原则,故名思议则是本质的意思。
所谓擒贼先擒王,研究设计模式自然要先了解设计原则,所有的模式都是在这些原则的基础之上发展起来的,有的是侧重一个,有的是多个都有所涉及。
看完设计模式之后,我感觉到每个模式都有这些原则的影子,还渗透着面向对象的三大属性,也觉得这些原则也都有相通之处,,正是有了他们才使我们由代码工人转为艺术家。
下面我来点评一下六大原则,望各位拍砖:
1、单一职责原则(Single Responsibility Principle,简称SRP)
单一职责原则,就一个类而言,应该仅有一个引起它变化的原因。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或者一直这个类完成其他职责的能力。
这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破
坏。
而软件设计真正要做的许多内容,就是发现职责,并把这些职责相互分离。
一句话点评:高内聚低耦合的绝佳体现,不要乱拉关系,独善其身挺好。
2、开放--封闭原则(The Open-Closed Principle,简称OCP)
开放--封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可以修改。
即对于扩展是开放的,对于更改是封闭的。
我们不可能做到未卜先知,在设计的时候尽可能让一个类足够好,设计好了就不要去修改了;不能完全封闭的情况下,当发生变化时,我们就创建抽象来隔离以后发生的同类变化。
一句话点评:开放扩展,封闭更改,开合有度是一门艺术。
开放封闭原则(OCP,Open Closed Principle)是所有面向对象原则的核心。
软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。
其他的设计原则,很多时候是为实现这一目标服务的,例如以Liskov替换原则实现最佳的、正确的继承层次,就能保证不会违反开放封闭原则。
关于开放封闭原则,其核心的思想是:
软件实体应该是可扩展,而不可修改的。
也就是说,对扩展是开放的,而对修改是封闭的。
因此,开放封闭原则主要体现在两个方面:
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
“需求总是变化”、“世界上没有一个软件是不变的”,这些言论是对软件需求最经典的表白。
从中透射出一个关键的意思就是,对于软件设计者来说,必须在不需要对原有的系统进行修改的情况下,实现灵活的系统扩展。
而如何能做到这一点呢?
只有依赖于抽象。
实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。
让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和对多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。
这是实施开放封闭原则的基本思路,同时这种机制是建立在两个基本的设计原则的基础上,这就是Liskov替换原则和合成/聚合复用原则。
关于这两个原则,我们在本书的其他部分都有相应的论述,在应用反思部分将有深入的讨论。
对于违反这一原则的类,必须进行重构来改善,常用于实现的设计模式主要有Template Method模式和Strategy模式。
而封装变化,是实现这一原则的重要手段,将经常发生变化的状态封装为一个类。
3、依赖倒转原则(Dependence Inversion Principle )
依赖倒转原则,指高层模块不应该依赖低层模块,两个都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。
说白了就是要针对接口编程,不要对实现编程。
举个例子:计算机硬件中,如果内存坏了,那么只需要换一个内存条就可以了,而不需要去换一个主板,在这里内存是一个接口类,只要符合他的规格要求就行,无论是那一根。
一句话点评:搞建筑时要做设计师,而不是砖瓦工,抽象的蓝图要靠具体的材料一点点实现。
抽象不应该依赖于细节,细节应当依赖于抽象。
要针对接口编程,而不是针对实现编程。
传递参数,或者在组合聚合关系中,尽量引用层次高的类。
主要是在构造对象时可以动态的创建各种具体对象,当然如果一些具体类比较稳定,就不必再弄一个抽象类做它的父类,这样有画蛇添足的感觉。
优点:
系统扩展灵活。
缺点:
需要大量的类。
4、里氏代换原则(Liskov Substitution Principle,简称LSP)
里氏代换原则,子类型必须能够替换掉他们的父类型。
在软件里面,把父类都替换成其子类,程序的行为不会发生变化。
正是由于子类型的可替换性才使得使用父类型的模块在无需修改的情况下就可以扩展。
一句话点评:长辈给了你继承的权利就一定要做赡养的义务,把长辈的职责都要承担起来。
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
5、迪米特法则(Law of Demeter)
迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。
如果其中一个类需要调用另一个类的某一个方法时,可以通过第三者转发这个调用。
类之间的耦合越弱,就越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。
主要是强调了类之间的松耦合。
6、合成/聚合复用原则(Composition/Aggregation Principle],简称CARP)
合成聚合复用原则,尽量使用合成/聚合,尽量不使用类继承。
合成聚合是“has a”的关系,而继承是“is a”的关系。
由于继承是一中强耦合的结构,父类变,子类必变。
所以不是“is a”关系,我们一般不要用继承。
优先使用合成聚合复用原则,有助于保持每个类的封装,降低继承的层次。
一句话点评:优生优育,不要盲目繁衍。
public class FlyweightFactory{
private HashMap flyweights = new HashMap();
public Flyweight getFlyweight(String key){
if(flyweights.containsKey(key)){
return (Flyweight)flyweights.get(key);
}
else{
Flyweight fw = new ConcreteFlyweight();
flyweights.put(key,fw);
return fw;
}
}
}。