设计模式总结
设计模式(Design Patterns)是可复用面向对象软件的基础,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码,让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。
一. 首先看看设计模式的分类:
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者
模式、解释器模式。
其他模式:并发型模式和线程池模式。
二. 设计模式中用到的设计原则
1.开闭原则(Open Close Principle)
开闭原则说的是对扩展开放,对修改关闭。按照开闭原则在程序代码需要进行扩展的时候不能对原有的程序进行修改而是要对程序实现热插拔的效果。
这样一来程序的易复用和可扩展性就能得到大大提升。
2.里氏代换原则(Liskov Substitution Principle)
里氏代换原则(LSP)中说,任何基类出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当扩展类可以替换掉基类,软件的单位不受到影响
时,基类才能真正的被复用,而扩展类也能够在基类的基础上增加新的行为。LSP是开闭原则的补充。实现开闭原则的关键步骤就是抽象化。而基类与
扩展类的继承关系就是抽象化的具体实现。所以LSP是对实现抽象化的具体步骤的规范。
3. 依赖倒转原则(Dependence Inversion Principle)
依赖倒转原则是开闭原则的基础,具体是说要针对接口编程而不是针对具体实现编程。为交互对象之间的松耦合设计而努力。
4. 接口隔离原则(Interface Segregation Principle)
接口隔离原则是说要使用多个隔离的接口,而不要使用单个接口。其作用是降低对象之间的耦合度。
5. 迪米特法则(Demeter Principle)
迪米特法则也叫最少知道原则。意思是对象之间应该尽量少的知道对方的信息。使得对象之间在一定程度上是相对独立的,作用也是降低对象之间的依
赖程度。
6. 合成复用原则(Composite Reuse Principle)
意思就是多用组合少用继承。 更加灵活易于变化。
设计模式原则小结:
其实以上提到的各种原则目标大概只有一个:降低对象之间的耦合,增加程序的可复用性、可扩展性、可维护性。设计模式就是软件设计的一种思想,
从大型软件架构出发,为了可复用和可升级而努力。
三. 常用的23中设计模式
1. 策略模式(Strategy Pattern)
策略模式封装了一系列的算法策略族,这些策略是独立于客户的,并且这些策略是可以互换的。客户通过上下文交互类就可以只调用一个执行策略方法
就可以调用任何一个策略的实现并且可以在不同的策略之间切换。
对策略模式的详细介绍:
http://www.cnblogs.com/wxisme/p/4497535.html
2. 工厂模式 (Factory Pattern)
工厂模式有3种。简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式:
简单工厂模式也叫静态工厂模式,工厂类一般使用静态方法 通过接收的参数不同来返回不同的对象实例。但是对增加新产品无能为力,不增加代码无法扩展。
工厂方法模式:
避免了简单工厂的缺点,满足了OCP(开闭原则,对扩展开放,对修改关闭)原则。简单工厂只有一个工厂类,而工厂方法有一组实现了相同接口的工厂方法。
工厂方法模式的缺点:结构和代码复杂度高,但是可扩展性好,客户端编程难度小。综合考虑,简单工厂模式,简单有一定的
可扩展性。实际上简单工厂模式用的多。
抽象工厂模式:
抽象工厂模式可以增加产品族,但是不可以增加新产品。纵向扩展。抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产
品族中的产品对象。 关于工厂模式的详细介绍:
http://www.cnblogs.com/wxisme/p/4518599.html
http://www.cnblogs.com/poissonnotes/archive/2010/12/01/1893871.html
3. 单例模式 (Singleton Pattern)
单例模式保证了一个类在同一时间内JVM中只有一个实例化对象存在。单例模式确保一个类只有一个实例,并只提供一个全局访问点。单例模式的意义
在于它可以保证只有一个实例化对象,在一定情况下可以降低系统开销,对于只能有一个实例的类来说保证了系统的稳定性和安全性。
单例模式的实现方式主要有:饿汉式、懒汉式、双重检测锁、静态内部类、枚举。
关于单例模式的具体实现和详细介绍:
http://www.cnblogs.com/wxisme/p/4517343.html
4. 建造者模式 (Constructor Pattern)
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的
属性。建造者模式的意义在于实现了构建和装配的解耦,实现了构建算法和装配算法的解耦,使用于构建过程复杂的情况。
关于建造者模式的例子:
http://www.cnblogs.com/wxisme/p/4520998.html
5. 原型模式 (Prototype Pattern)
原型模式只要用来实现对象的复制,对于创建或者复制一个对象的实例非常复杂的时候就可以使用原型模式来拷贝。在一个复杂的对象中往往还有其他
的对象属性,这样如果直接复制将导致两个对象中的对象属性实际上是指向同一个属性实例的。这就需要进行深度克隆。实现深度克隆的方法有两种一
种是实现Cloneable接口,重写clone()方法,另一种是通过序列化反序列化来获取对象的拷贝。
关于原型模式的例子:
http://www.cnblogs.com/wxisme/p/4540634.html
6. 适配器模式 (Adaptor Pattern)
适配器模式将一个接口转换成客户期望的另一个接口,目的是次消除由于接口不匹配导致的兼容性问题。主要分为三类:类的适配器模式、对象的适配
器模式、接口的适配器模式。适配器也可以说成接口与接口之间的转换器。适配器的一个典型的应用是:JavaIO中的转换流,可以将字节流转换成字符
流,是流的适配器。
关于适配器模式的例子:
http://www.cnblogs.com/wxisme/p/4522632.html
7. 装饰模式 (Decorator Pattern)
装饰器模式:动态地给一个对象添加一些额外的职责或者行为。就增加功能来说, Decorator模式相比生成子类更为灵活。装饰器模式提供了改变子类
的灵活方案。装饰器模式在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
使用装饰器模式,可以避免代码重复和具体子类数量的增加。
关于装饰模式的例子与解释:
http://www.cnblogs.com/wxisme/p/4510852.html
8. 代理模式 (Proxy Pattern)
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,
以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是
通过调用委托类的对象的相关方法,来提供特定的服务。 按照代理的创建时期,代理类可以分为两种。 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 动态代理:在程序运行时,运用反射机制动态创建而成。
更多介绍:
http://www.cnblogs.com/wxisme/p/4550574.html
9.外观模式 (Facade Pattern)
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。简单的说,外观模式就是把复杂
的系统的具体操作封装起来,只暴露一个简单的接口,做和众多子系统之间松耦合。外观模式是为了解决类与类之家的依赖关系的,像spring一样,可
以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度。
关于外观模式的例子:
http://www.cnblogs.com/wxisme/p/4541085.html
10.桥接模式(Bridge Pattern)
桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化。这样一来两个
维度之间就可以任意的扩展和变化而不影响对方。桥接模式极大的提高了系统的可扩展性,可以大大降低维护的成本。
关于桥接模式:
http://www.cnblogs.com/wxisme/p/4553362.html
11. 享元模式(Flyweight Pattern)
享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。FlyWeightFactory负责创
建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一
个新对象,FlyWeight是超类。一提到共享池,我们很容易联想到Java里面的JDBC连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一
些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接
来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进
来,这样就节省了空间,减少了实例的数量。
关于享元模式的例子:
http://www.cnblogs.com/wxisme/p/4549858.html
12. 模板方法模式(Template Method Pattern)
模板方法模式是编程中经常用到的模式,它定义了一个操 作中的算法骨架,将某些步骤延迟到子类中实现。这样,新的子类可以在 不改变一个算法
结构的前提下重新定义该算法的某些特定的步骤。处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不 能确定。因此采用工厂方法模式
将这个节点的代码实现转移给子类完成 即:处理步骤父类中定义好,具体实现延迟到子类中定义。 模板方法模式的使用场景:实现一个算法时,整
体步骤很固定。但是某些部分易变。易变部分可以抽象出来,供子类实现。
模板方法模式的具体例子:
http://www.cnblogs.com/wxisme/p/4540600.html
13. 观察者模式(Observer Pattern)
观察者模式定义了对象之间的一对多的依赖,这样一来,当一个状态发生变化时,它的所有依赖者都会收到通知并自动更新。;类似于邮件的订阅一样
当一个用户订阅了某个主题时,每当主题有变化或者更新的时候都会通知订阅的用户,当然这种订阅可以注册也可以注销。同样和电子邮件一样,订阅
也有推送式和拉取式,就像SMTP协议和POP3协议一样。
关于观察者模式的例子:
http://www.cnblogs.com/wxisme/p/4499147.html
14. 迭代器模式(Iterator Pattern)
迭代器模式非常好理解就是提供一种功能来遍历一个集合容器,不管是C++还是Java都在集合容器里提供了一种遍历各种容器的迭代器,Java中还内置
了Iterator接口。
关于迭代器模式的例子:
http://www.cnblogs.com/wxisme/p/4541008.html
15. 责任链模式(Chain of Responsibility)
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上
的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地
重新组织和分配责任。说到责任链模式我想到了多功能的链表,还有DNS的递归解析方式。好像都是责任链。
责任链的例子:
http://www.cnblogs.com/wxisme/p/4550712.html
16. 命令模式(Command Pattern)
命令模式就是将一个请求封装为一个对象,从而使我们可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
也称之为:动作模式,事务模式。简单的说命令模式将命令的发出者、命令的传递者、命令的执行者独立出来,满足了松耦合的要求,易于维护和更改。
命令模式的例子:
http://www.cnblogs.com/wxisme/p/4540588.html
17. 备忘录模式(Memento Pattern)
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,
并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。简单的说备
忘录模式就是在必要的时候可以恢复到对象的某一个状态。对对象的备忘其实就是对这个对象某个状态的深度拷贝。这让我想起了原型模式。等等我还
想起了DBMS中事务的撤销和数据恢复还有DBMS的日志备份系统。
关于备忘录模式的例子:
http://www.cnblogs.com/wxisme/p/4540682.html
18. 状态模式(State Pattern)
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改
变其行为。这个对象看上去就像是改变了它的类一样。状态模式可以让对象在不同的状态之间切换,并且随着对象状态的改变其行为也跟着改变。
关于状态模式的例子:
http://www.cnblogs.com/wxisme/p/4544432.html
19. 访问者模式(Visitor Pattern)
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因
为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优
点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就
是增加新的数据结构很困难。
访问者模式的详细介绍:
http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html
20. 中介者模式(Mediator Pattern)
中介者模式是对象的行为模式。中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用。从而使它们可以较松散地耦合。当
这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立地变化。中介
者模式就是把对象之间的复杂网状关联结构化解成星形结构使得对象之间解耦。
关于中介者模式的详细举例:
http://www.cnblogs.com/wxisme/p/4546723.html
http://www.cnblogs.com/java-my-life/archive/2012/06/20/2554024.html
21. 解释器模式(Interpreter Pattern)
解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解
释这个语言中的句子。解释器模式在大多数情况下是用不到的。解释器模式中有一个Context上下文类用来获取要解析语句的输入流。每个表达式类中
有一个interpret(Context c)方法用来解析语句的语义并返回正确的结果。
关于解释器模式请看:
http://www.cnblogs.com/java-my-life/archive/2012/06/19/2552617.html
22. 组合模式(Composite Pattern)
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。有时候又叫做部分
-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序
与复杂元素的内部结构解耦。组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于
分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是
文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式。
组合模式请看:
http://www.cnblogs.com/wxisme/p/4692637.html
小结:
各种设计模式应该是经常组合起来用的而并不是单独使用。只有在适合的场景下把合适的设计模式组合起来才能发挥其巨大威力。但是也要注意过度的
使用设计模式可能导致代码被过度工程化。用该总是用最简单的解决方案完成工作,并在真正需要的地方使用。 其他的设计模式还有:架构模式、领域特定模式、业务流程模式、用户界面设计模式、反模式等等,并不是用到了哪个设计模式就要按照它固有的格式来用,这个要看具体的场景,灵活而准确的用好设计模式非一日之功啊,需要不断的去积累经验。在前进的路上。。。
现在23种设计模式复习完毕(抽象工厂模式归到工厂模式中),具体的示例和每一种设计模式的用法和特点请参考我的博客:设计模式。
他山之石 :
设计模式总结 :
http://blog.csdn.net/xtwolf008/article/details/8807006
设计模式专题 :
http://zzk.cnblogs.com/s?w=blog%3Ajava-my-life+Java%E4%B8%8E%E6%A8%A1%E5%BC%8F&t=
如有错误请指正:)
如要引用请指明出处:http://www.cnblogs.com/wxisme/p/4693094.html