SilverLining's Blog

设计模式总结与对比

前言

本文来总结回顾一下之前学习的 26 中设计模式。

在正文开始之前,先抛出一个问题:我们为什么要学习设计模式?

GoF 的设计模式是 Java 基础知识和 J2EE 框架知识之间一座隐性的"桥"

设计模式和 J2EE 在思想和动机上是一脉相承的,我总结了以下几个原因:

  1. 设计模式更抽象。 J2EE 是具体的产品代码,我们在日常工作中就可以接触到,而设计模式在对每个应用时才会产生具体代码;
  2. 设计模式是比 J2EE 等框架软件更小的体系结构, J2EE 中许多具体程序都是应用设计模式实现的。当你深入到 J2EE 的内部代码研究时,这点尤其明显。因此,如果不具备设计模式的基础知识,你可能很难理解 J2EE 的代码,从而难以灵活应用 J2EE 框架;
  3. J2EE 只是适合企业计算应用的框架软件,但是 GoF 的设计模式几乎可以用于任何应用。因此 GoF 的设计模式是 J2EE 的重要理论基础之一。

所以说,GoF 的设计模式是 Java 基础知识和 J2EE 框架知识之间一座隐性的" 桥" 。

七大设计原则总结

设计原则 总结归纳 主要目的
开闭原则 (Open-Close) 对扩展开放,对修改关闭 减少维护带来新的风险
依赖倒置原则 (Dependence Inversion) 高层模块不应依赖低层 更利于代码结构的升级扩展
单一职责原则 (Simple Responsibility) 一个类只干一件事 便于理解,提高代码可读性
接口隔离原则 (Interface Segregation) 一个接口只干一件事 减小功能解耦,高聚合、低耦合
迪米特法则 (Law of Demeter) 不该知道的不要知道 只和朋友交流,不和陌生人说话,减少代码冗余
里氏替换原则 (Liskov Substitution) 子类重写方法功能发生改变,不应该影响父类方法的含义 防止继承泛滥
合成复用原则 (Composite/Aggregate Reuse) 尽量使用组合实现代码复用,而不使用继承 降低代码耦合

设计模式是前人经验的总结,形成方法论供后人借鉴使用。设计模式是在我们迷茫时提供的一种解决问题的方法论,或者说用好设计模式可以对一些问题防范于未然。

设计模式也是一门艺术。艺术来源于生活,而设计模式则来源于解决实际的代码问题的经验总结,我们不要为了套用设计模式而去使用设计模式。

GOF 23 设计模式

分类回顾

GOF 23 种设计模式简单分类如下:

相互依赖关系如下:

从经验来看,以上设计模式的使用(可能需要自己造轮子)频率大致分布如下:

设计模式类型 高频使用 低频使用
创建型模式 (Creational) 厂方法模式 (Factory Method) 、抽象工厂模式 (Abstract Factory) 、单例模式 (Singleton) 、 建造者模式 (Builder ) 原型模式 (Prototype)
结构型模式 (Structural) 代理模式 (Proxy) 、门面模式 (Facade) 、装饰器模式 (Decorator) 、享元模式 (Flyweight) 、适配器模式 (Adapter) 、组合模式 (Composite) 桥接模式 (Bridge)
行为型模式 (Behavioral) 模板方法模式 (Template Method) 、策略模式 (Strategy) 、责任链模式 (Chain of Responsibility) 、状态模式 (State) 备忘录模式 (Memento) 、观察者模式 (Observer) 、迭代器模式 (Iterator) 、中介者模式 (Mediator) 、命令模式 (Command) 、解释器模式 (Interpreter) 、访问者模式 (Visitor)

思想总结

创建型模式

设计模式 一句话归纳 目的 现实案例 典型应用案例
工厂模式 (Factory) 产品标准化,生产更高效 封装对象创建的细节 实体工厂 LoggerFactory 、 Calender
单例模式 (Singleton) 世上只有一个你 保证对象独一无二 公司 CEO BeanFactory 、 Runtime
原型模式 (Prototype) 拔一根猴毛,吹出千万个 高效创建对象 克隆技术 ArrayList 、 PrototypeBean
建造者模式 (Builder) 高配中配低配,任你挑选 开放个性配置步骤 DIY 组装 StringBuilder 、 BeanDefinitionBuilder

结构型模式

设计模式 一句话归纳 目的 现实案例 典型应用案例
代理模式 (Proxy) 没有资源没时间,得找中介来帮忙 对象职责增强 房产中介,婚恋中介 ProxyFactoryBean 、 JdkDynamicAopProxy 、 CglibAopProxy
门面模式 (Facade) 打开一扇门,走向全世界 提供统一的子系统的访问入口 公司前台,导医台 JdbcUtils 、 RequestFacade
装饰器模式 (Decorator) 奶油蛋糕巧克力蛋糕,都是蛋糕 基于继承体系的灵活扩展 煎饼、蛋糕 BufferedReader 、 InputStream
享元模式 (Flyweight) 优化资源配置,减少重复浪费 共享资源池 全国社保联网 String 、 Integer 、 ObjectPool
组合模式 (Composite) 一条绳子上的蚂蚱 统一(有相关性的)整体和个体 组织架构树 HashMap 、 SqlNode
适配器模式 (Adapter) 老系统新需求,亡羊补牢 patch 来凑 使相关功能适配新的接口需求 电源适配器 AdvisorAdapter 、 HandlerAdapter
桥接模式 (Bridge) 约定优于配置 不使用继承,耦合多个不同维度的对象 小桥 DriverManager

行为型模式

设计模式 一句话归纳 目的 现实案例 典型应用案例
委派模式 (Delegate) 这个需求很简单,怎么实现我不管 只对结果负责 授权委托书 ClassLoader 、 BeanDefinitionParserDelegate
模板模式 (Template) 流程全部标准化,细节操作你行你上 逻辑复用,统一封装 把大象装进冰箱分几步 JdbcTemplate 、 HttpServlet
策略模式 (Strategy) 条条大道通北京,具体哪条你来定 把选择权交给用户 选择支付方式 Comparator 、 InstantiationStrategy
责任链模式 (Chain of Responsibility) 各人自扫门前雪,莫管他人瓦上霜 解耦链式逻辑 报销签字流程 FilterChain 、 Pipeline
迭代器模式 (Iterator) 流水线上坐一天,每个包裹扫一遍 统一的集合对象访问方式 物流分拣出库 Iterator
命令模式 (Command) 运筹帷幄之中,决胜千里之外 解耦请求和处理逻辑 遥控器 Runnable 、 TestCase
状态模式 (State) 状态驱动行为,行为决定状态 状态和行为绑定 订单状态处理 Lifecycle
备忘录 (Memento) 给我一剂 “后悔药” 状态备份 草稿箱 StateManageableMessageContext
中介者 (Mediator) 联系方式我给你,怎么搞定靠自己 统一平级网状资源的管理 朋友圈 Timer
解释器模式 (Interpreter) 方言翻译家 实现特定语法解析 摩斯密码、数学表达式 Pattern 、 ExpressionParser
观察者模式 (Observer) 到点就通知我 解耦观察者与被观察者 闹钟 ContextLoaderListener
访问者模式 (Visitor) 横看成岭侧成峰,远近高低各不同 解耦数据结构和数据操作 不同人员不同的 KPI 考核指标 FileVisitor 、 BeanDefinitionVisitor

设计模式的联系和对比

  1. 单例模式和工厂模式
  1. 策略模式和工厂模式
  1. 策略模式和委派模式
  1. 模板方法模式和工厂方法模式
  1. 模板方法模式和策略模式
  1. 装饰者模式和静态代理模式
  1. 装饰者模式和适配器模式
  1. 适配器模式和静态代理模式
  1. 适配器模式和策略模式
  1. 代理模式和中介者模式
  1. 委派模式和代理模式
  1. 命令模式和策略模式
  1. 代理模式和装饰器模式
  1. 委派模式和责任链模式
  1. 工厂方法与抽象工厂
  1. 桥接模式与适配器模式
  1. 行为型模式、结构型模式、创建型模式
  1. 抽象工厂方法与模板方法
  1. 建造者模式 vs 装饰器模式
  1. 适配器模式 Vs 中介者模式
  1. 桥接模式与中介者模式
  1. 桥接模式与组合模式
  1. 门面模式与装饰器模式
  1. 门面模式与委派模式
  1. 享元模式与饿汉式单例
  1. 桥接模式与命令模式
  1. 适配器模式与策略模式
  1. 策略模式与模板模式