设计模式总结
是时候对设计模式做一下总结了。结合开发中的经验,会对23种设计模式中常用的设计模式进行一下说明举例,其余的也会在后面加深理解和增加实际使用经验后进行补充。
设计模式简介
GOF提出的设计模式主要是基于以下的面向对象设计原则。
- 对接口编程而不是对实现编程。
- 优先使用对象组合而不是继承。
模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。这里还会包含另一类设计模式:J2EE 设计模式。
模式分类 | 设计模式 |
---|---|
创建型模式 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式, 而不是使用 new 运算符直接实例化对象。 这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 | 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) |
结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 | 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Filter、Criteria Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) |
行为型模式 这些设计模式特别关注对象之间的通信。 | 责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式(Interpreter Pattern) 迭代器模式(Iterator Pattern) 中介者模式(Mediator Pattern) 备忘录模式(Memento Pattern) 观察者模式(Observer Pattern) 状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) |
J2EE 模式 这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。 | MVC 模式(MVC Pattern) 业务代表模式(Business Delegate Pattern) 组合实体模式(Composite Entity Pattern) 数据访问对象模式(Data Access Object Pattern) 前端控制器模式(Front Controller Pattern) 拦截过滤器模式(Intercepting Filter Pattern) 服务定位器模式(Service Locator Pattern) 传输对象模式(Transfer Object Pattern) |
工厂模式
抽象工厂模式
抽象工厂模式主要增加了抽象工厂类如AbstractFactory (抽象类),然后子类实现具体的工厂生产出系列对象。不过看到一些资料介绍说:
简单工厂模式是有一个专门生产某个产品的类。
工厂模式是鼠标工厂是个父类,有生产鼠标这个接口。戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。 后续直接调用鼠标工厂.生产鼠标()即可。
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。(增加系列化)
也就是 PC 厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。
单例模式
常见的共有一下几种方式:
- 懒汉式,线程不安全,getInstance()方法直接null判断创建。
- 懒汉式,线程安全,getInstance()方法添加synchronized内置锁同步处理控制。
- 饿汉式,线程安全,类加载classloader 机制保证线程安全,
private static Singleton instance = new Singleton();
- DCL双重校验锁,
null判断->synchronized(类锁)->null判断->创建单例对象
- 静态内部类,类加载classloader 机制保证线程安全
- 枚举实现,Effective Java推荐的单例实现方式,不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
其中自己实际开发中第4第5种方式使用得比较多,如果是没有lazy loading需求的场景,也会直接使用第3种实现方式。第6中枚举实现的方式自己没有在项目中实际使用过。
具体的代码实现请参考我的另一篇博客:静态内部类实现单例模式
建造者模式
非常常见的设计模式,在jdk源码中或其它常用组件或开源框架中就有很多的常见的应用。如JAVA 中的 StringBuilder/StringBuffer ,guava中的CacheBuilder,org.apache.httpcomponents.httpclient中的URIBuilder,Mybatis中的SqlSessionFactoryBuilder/XMLConfigBuilder等。
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。利用已有的一个原型对象,快速地生成和原型对象一样的实例。
原型模式的实现(实现克隆操作):
- clone方法:浅拷贝。
- 序列化:深拷贝。
在 JAVA 中:浅拷贝通过继承 Cloneable,重写 clone()(Cloneable实际上是一个空接口来限定特性和做判断,clone方法重写自Object类)。深拷贝通过实现 Serializable 读取二进制流。原型模式已经与 Java 融为浑然一体。
适配器模式
桥接模式
桥接模式架构上感觉和适配器模式有相似的地方,实际上是不同的作用和应用场景。