设 计 模 式
Time:2012-2-20
Author:Wang Huan
一.
设计模式的分类 | 创建型模式 | 5种 |
结构型模式 | 7种 | |
行为型模式 | 11种 | |
并发型模式 | ||
线程池模式 | ||
设计模式六大原则 | 开闭原则 | 对扩展开放,对修改关闭 |
里氏代换原则 | 子类必须能够替换成它们的基类 | |
依赖倒转原则 | 要依赖于抽象,不要依赖于具体 | |
接口隔离原则 | 使用多个隔离的接口,比使用单个接口好 | |
迪米特原则 | 最少知识原则,通过友元类来转达,降低耦合 | |
合成复用原则 | 合成/聚合与继承,分清Has-A和Is-A |
1.创建型模式:
·工厂方法模式·抽象工厂模式·单例模式·建造者模式·原型模式
2.结构型模式:
·适配器模式·装饰器模式·代理模式
·外观模式·桥接模式·组合模式
·享元模式
3.行为型模式:
·策略模式·模板方法模式·观察者模式
·迭代子模式·责任链模式·命令模式
·备忘录模式·状态模式·访问者模式
·中介者模式·解释器模式
二.
1.工厂方法模式:
① 应用场景:凡是出现了大量的类需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。如:Animal->pig,chicken,cattle,sheep…。
② 尽量使用静态工厂方法模式来进行类的创建,如Swing中的BorderFactory。
2. 抽象工厂模式:
应用场景:适用于类结构多变或有可能扩展的类创建中,但实际中我们大多数程序都需要给未来的维护留有扩展的余地,这才符合开闭原则,所以,大多数时候,我们都会采用抽象工厂模式。当然这并不表示普通的工厂方法没有适用的场合,如果类结构固定则可以使用,比如Swing中的BorderFactory。
3. 单例模式:
① 应用场景:适合于一个类只有一个实例的情况,比如系统的全局变量、全局存储区域、全局配置文件、全局操作函数。典型的情况是,那些对象的实例能够被整个软件系统的不同对象访问,因此需要一个全局的访问指针,这便是众所周知的单例模式的应用。如java中的Calendar。
② 一个标准的单例模式需要包含4个要素:
a) 拥有一个私有的静态实例,该实例禁止外部访问;
b) 拥有一个私有的默认构造函数,防止使用构造函数进行实例化;
c) 拥有一个静态工厂方法,并且必须是同步的,防止多线程环境下同时执行;
d) 重写clone()方法,并返回当前实例,默认的clone()函数会创建新的实例。
4. 建造者模式:
与工厂模式的本质区别:工厂模式只关注(复合)类,不关注类(的各部分)是怎么创建的,但是建造者模式就是关注复合类的各部分是怎么创建的。比如创建一部汽车,工厂模式只关注汽车本身,而建造者模式关注的是汽车的各零件是如何创建并组装成为汽车的。如java里的StringBuilder和 ProcessBuilder。
5. 原型模式:
① 通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例,被复制的实例就是我们所称的“原型”。
Public class Prototype implements cloneable{
/*
*浅复制
*/
Public object clone() throws CloneNotSupportException{
Prototype pro = (Prototype)super.clone();
Return pro;
}
}
调用prototype模式很简单:
Prototype obj = new Prototype();
Prototype obj2 = obj.clone();
② 应用场景:多用于创建复杂的或者耗时的实例,或者创建值相等只是命名不一样的同类数据。原型模式关注的是大量的相似对象的创建问题。
6. 适配器模式:
如果需要将一个类转化为另一个类时就可以使用适配器模式,分为3种不同的子模式:
① 类的适配器模式:当希望将一个类转化为满足另一个接口时,可以模仿Adapter的做法来构造一个新的适配器类,该类继承原有的类并实现新的接口即可;
② 对象的适配器模式:当希望将一个对象转化为满足另一个接口时,可以模仿Wrapper的做法来构造一个新的包装类,该类调用原有的类并实现新的接口即可;
③ 类的适配器模式:当不希望实现一个接口的所有方法时,可以模仿DefaultWrapper的做法来构造一个抽象类,给出所有方法的默认实现,这样从这个抽象类继承下去的子类就不必实现所有的方法了。
如:Java中的Iterator适配器、Enumeration适配器、AWT事件适配器、I/O字节流到字符流的适配器。
7. 装饰器模式:
① 特点:顾名思义,就是动态地给一个对象添加一些额外的职责,一句话总结为:保持接口,增强性能。对象的适配器是把一个对象适配成了另一个对象,而装饰器模式将丰富目标对象的功能但不改变它的接口。对象适配器模式将一个圆形变成了正方形,而装饰器模式则不改变形状而改变它的外观颜色。
② 应用场景:
· 需要扩展一个类的功能,或给一个类增加附加责任;
· 需要动态的给一个类增加或撤销功能;
· 需要增加由一些基本的排列组合产生大量的功能,从而使继承关系变得不现实;
如:sitemesh装饰器、I/O输入输出流管道的装饰器模式
8 代理模式:
给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。
9 外观模式:
客户访问一个子系统,子系统超级复杂(有很多类),为降低耦合,子系统提供一个接口给客户访问,屏蔽了子系统的内部实现,降低了耦合。与代理模式类似,代理模式是一对一的代理,而外观模式是一对多的代理;与装饰模式类似,装饰模式为对象增加功能,而外观模式只是提供一个简单的调用方式。
应用场景:凡是一个子系统提供一个统一的外部接口,而不需要了解子系统的内部实现(有点像构件)的类都属于外观模式的应用,比如JDBC、Hibernate。
10 桥接模式:
将抽象化与实现化脱耦,使得二者可以独立变化。
应用场景:JDBC桥DriverManager
11 组合模式:
将对象组合成树形结构以表示“部分-整体”的层次结构,客户程序可以像处理简单元素一样来处理复杂元素,从而使客户程序与复杂元素的内部结构解耦。
应用场景:AWT容器Container
12享元模式:
通过使用共享的方式,达到高效地支持大量的细粒度对象,节省占用的空间资源,使系统的性能得到改善。
应用场景:数据库连接池。
13 策略模式:
定义一个算法的系列,将其各个封装,并且使它们有交互性,使得算法在用户使用的时候能独立改变。
应用场景:AWT布局管理器、Swing边界类Border。
14 模板方法模式:
让抽象类给出程序的骨架和轮廓,在抽象类中编写主方法,并申明一些抽象方法,
迫使子类实现剩余的逻辑。简单的说就是父类完全控制着子类的业务逻辑,而子类根据不同的业务对父类的所有抽象方法进行实现。
应用场景:知道了一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关,这时就可以使用父类控制逻辑,由子类实现逻辑。如HTTP请求处理类HTTPServlet。
15 观察者模式:
对象间的一种一对多的依赖关系,,让多个观察者对象同时关注同一个对象,当该
对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
应用场景:Java里的Observable和Observer、AWT事件监听器。
16 迭代子模式:
迭代子模式可以顺序地访问聚集中的对象而不必暴露聚集的内部数据结构。
应用场景:凡是有数据聚集的地方都可以使用迭代子模式来进行数据迭代。如:
Java集合类迭代子Iterator和Enumberation、Resultset。
17 责任链模式:
很多对象由每一个对象将其下家的引用而连接起来形成一条链,请求在这个链上传
递,直到链上某一个对象决定处理此请求。发出请求的这个客户端并不知道链上的哪一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任。
应用场景:凡是具有过滤和管道特征的应用都属于责任链模式。如:Java中的Filter过滤器、Unix中的管道符等等。
18 命令模式:
命令模式主要解决在软件构件过程中,行为发起者与行为实现者之间的紧耦合问
题。它将一个发起者请求封装成一个对象,将发起者和执行者分开来,通过命令的方式实现。
应用场景:凡是需要将调用和实现分开处理的情况都可以使用命令模式。如:MVC将表现层和业务层分开实现、AWT界面事件处理。
19 备忘录模式:
备忘录模式的主旨是存储一个对象的快照,即在不破坏封装的前提下,捕获一个对
象的内部状态,并在该对象之外保存这个状态。这样以后可以将该对象恢复到原先保存的状态。
应用场景:使用备忘录模式来实现保存对象的历史状态。如:Java中的Session和Application。
20 状态模式:
在对象的状态改变时,会同时改变其行为。如MSN和QQ的在线状态切换时,对
应的权限动作和好友显示也回发生变化。
应用场景:如果某个对象的属性不同,对象的行为就不一样时就可以使用状态模式。如:Java工作流引擎(JBPM 、OSWorkflow)。
21 访问者模式:
核心思想:操作改变,数据结构不变。访问者模式是一种分离对象的数据结构和行
为的方法,通过这种分离,可以为一个已存在的类或类群(即被访问者)增加新的操作(即访问者)而无须为它们进行任何修改。
应用场景:Java Annotation。
22 中介者模式:
如果有多个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修
改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用中介者模式,化多对多的关系为一对多的关系,可以降低系统的耦合度,提高可扩展性。
应用场景:Java多线程数据共享。
23 解释器模式:
解释预先定义的文法。
应用场景:主要应用在使用面向对象语言开发编译器中。如:Java正则表达式解释器。