java设计模式

设计模式是为了可扩展性,不要为了使用设计模式而使用

概念

设计模式,即Design Patterns,是指在软件设计中,被反复使用的一种代码设计经验。使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性。

创建型模式

创建型模式关注点是如何创建对象,其核心思想是要把对象的创建和使用相分离,这样使得两者能相对独立地变换,共五种:

  • 工厂方法模式FactoryMethod: 定义一个用于创建产品的接口,由子类决定生产什么产品
  • 抽象工厂模式AbstractFactory: 提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品
  • 单例模式Singleton: 某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式
  • 建造者模式Builder: 将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象
  • 原型模式Prototype: 将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例

结构型模式

结构型模式主要涉及如何组合各种对象以便获得更好、更灵活的结构,共七种:

  • 适配器模式Adapter: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作
  • 装饰器模式Decorator: 动态的给对象增加一些职责,即增加其额外的功能
  • 代理模式Proxy: 为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性
  • 外观模式Facade: 为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问
  • 桥接模式Bridge: 将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度
  • 组合模式Composite: 将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性
  • 享元模式Flyweight: 运用共享技术来有效地支持大量细粒度对象的复用

行为型模式

行为型模式主要涉及算法和对象间的职责分配。这些设计模式是特别侧重于对象之间的通信,通过使用对象组合,行为型模式可以描述一组对象应该如何协作来完成一个整体任务,共十一种:

  • 策略模式Strategy: 定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户
  • 模板方法模式TemplateMethod: 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤
  • 观察者模式Observer: 多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为
  • 迭代器模式Iterator: 提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示
  • 责任链模式Chain of Responsibility: 把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合
  • 命令模式Command: 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开
  • 备忘录模式Memento: 在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它
  • 状态模式State: 允许一个对象在其内部状态发生改变时改变其行为能力
  • 访问者模式Visitor: 在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问
  • 中介者模式Mediator: 定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解
  • 解释器模式Interpreter: 提供如何定义语言的文法,以及对语言句子的解释方法,即解释器

见名思意, 代码中出现了类名存在如Adapter、Factory、Decorator等,可以联想到对应的设计模式,无论自己编写还是查阅他人代码

设计模式需要满足:

  • 开闭原则(Open Close Principle): 软件应该对扩展开放,而对修改关闭。这里的意思是在增加新功能的时候,能不改代码就尽量不要改,如果只增加代码就完成了新功能,那是最好的
  • 里氏替换原则(Liskov Substitution Principle): 即如果我们调用一个父类的方法可以成功,那么替换成子类调用也应该完全可以运行
  • 依赖倒转原则(Dependence Inversion Principle): 针对接口编程,依赖于抽象而不依赖于具体
  • 接口隔离原则(Interface Segregation Principle): 使用多个隔离的接口,比使用单个接口要好
  • 迪米特法则(Demeter Principle): 一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立
  • 合成复用原则(Composite Reuse Principle): 尽量使用合成/聚合的方式,而不是使用继承

特别感谢廖雪峰老师的文章推荐学习!

1
//todo

模式间的区别

装饰器模式VS代理模式

装饰模式 注重对对象功能的扩展,它不关心外界如何调用,只注重对对象功能的加强,装饰后还是对象本身

代理模式 注重对对象某一功能的流程把控和辅助。它可以控制对象做某些事,偏重因自己无法完成或自己无需关心,需要他人干涉事件流程,更多的是对对象的控制,重心是为了借用对象的功能完成某一流程,而非对象功能如何。

建造者模式VS桥接模式

最终目标都是构造大对象

建造者模式:初始化每个变量的时候,都返回了最终的对象,就是你可以不完全链式的点完所有变量,亦可得到可使用的对象;每个成员变量在构造时是同层次的

桥接模式: 初始化时,每个部分缺一不可;每个成员变量的层级不同,使用最小的部件,逐层往上初始化直至整个对象,类似于用 发动机-> 引擎模块 -> 引擎模块 + 车壳(类比文中品牌)-> 完整的汽车 【一级连接一级,有点桥接的意思】

享元模式VS单例模式

  • 享元设计模式是一个类有很多对象,而单例是一个类仅一个对象。

  • 享元模式是为了节约内存空间,提升程序性能,而单例模式则主要是出于共享状态的目的。

工厂方法模式VS抽象工厂模式VS模板方法模式

  • 简单工厂能把具体实现包装起来,让客户端真正达到面向接口编程

  • 工厂方法可以在高层进行编码,让服务端的产品线真正达到面向接口编程

  • 抽象工厂能聚合整个产品簇,让整个服务端的多个产品线真正达到面向接口编程

  • 模板方法同样是在高层进行编码,也同样是面向接口编程。

    但工厂方法及抽象工厂方法着重抽象的是产品,而模板方法着重抽象的是步骤。
    而我们通常会两者一起结合起来使用。

GOF是设计模式的经典名著Design Patterns: Elements of Reusable Object-Oriented Software(中译本名为《设计模式——可复用面向对象软件的基础》)的四位作者,他们分为是:Elich Gamma、Richard Helm、Ralph Johnson、以及John Vlissides。这四个人常被称为Gang of Four, 即四人组,简称Gof