六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)

目录

    • 1.简介
    • 2.GoF23
    • 3.软件开发的7条原则
    • 4.具体介绍
      • 4.1 创建型模式
        • 4.1.1 单例模式
        • 4.1.2 原型模式
        • 4.1.3 简单工厂模式
        • 4.1.4 工厂模式
        • 4.1.5 抽象工厂模式
        • 4.1.6 建造者模式
      • 4.2 结构型模式
        • 4.2.1代理模式
        • 4.2.2适配器模式
        • 4.2.3 桥接(Bridge)模式
        • 4.2.4装饰(Decorator)模式
        • 4.2.5外观(Facade)模式
        • 4.2.6 享元(Flyweight)模式
        • 4.2.7 组合(Composite Pattern)模式
      • 4.3行为型模式
        • 4.3.1模板方法(Template Method)模式
        • 4.3.2策略(Strategy)模式
        • 4.3.3命令(Command)模式
        • 4.3.4责任链(Chain of Responsibility)模式
        • 4.3.5状态(State)模式
        • 4.3.6观察者(Observer)模式
        • 4.3.7中介者(Mediator)模式
        • 4.3.8 迭代器(Iterator)模式
        • 4.3.9访问者(Visitor)模式
        • 4.3.10备忘录(Memento)模式
        • 4.3.11解释器(Interpreter)模式

1.简介

设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第1张图片

这 23 种设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解。

当然,软件设计模式只是一个引导,在实际的软件开发中,必须根据具体的需求来选择:
对于简单的程序,可能写一个简单的算法要比引入某种设计模式更加容易;
但是对于大型项目开发或者框架设计,用设计模式来组织代码显然更好。

详细文章

2.GoF23

  1. 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
  2. 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
  3. 工厂方法(Factory Method)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。
  4. 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
  5. 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
  6. 代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
  7. 适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
  8. 桥接(Bridge)模式:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
  9. 装饰(Decorator)模式:动态的给对象增加一些职责,即增加其额外的功能。
  10. 外观(Facade)模式:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问。
  11. 享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。
  12. 组合(Composite)模式:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。
  13. 模板方法(TemplateMethod)模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
  14. 策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
  15. 命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
  16. 职责链(Chain of Responsibility)模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
  17. 状态(State)模式:允许一个对象在其内部状态发生改变时改变其行为能力。
  18. 观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。
  19. 中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系, . 降低系统中对象间的耦合度,使原有对象之间不必相互了解。
  20. 迭代器(Iterator)模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
  21. 访问者(Visitor)模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
  22. 备忘录(Memento)模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。
  23. 解释器(Interpreter)模式:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。

六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第2张图片

3.软件开发的7条原则

  1. 开闭原则:软件实体应当对扩展开放,对修改关闭。含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
  2. 里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立。通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。
  3. 依赖倒置原则:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。其核心思想是:要面向接口编程,不要面向实现编程。
  4. 单一职责原则:又称单一功能原则。一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。
  5. 接口隔离原则:客户端不应该被迫依赖于它不使用的方法。该原则还有另外一个定义:一个类对另一个类的依赖应该建立在最小的接口上。以上两个定义的含义是:要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
  6. 迪米特法则:又叫作最少知识原则。只与你的直接朋友交谈,不跟“陌生人”说话。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。
  7. 合成复用原则:又叫组合/聚合复用原则。它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。如果要使用继承关系,则必须严格遵循里氏替换原则。

4.具体介绍

4.1 创建型模式

创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。

4.1.1 单例模式

单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第3张图片
单例模式的扩展:多例模式
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第4张图片

4.1.2 原型模式

原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。在生活中复制的例子非常多,这里不一一列举了。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第5张图片
原型模式的扩展:带原型管理器的原型模式
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第6张图片

4.1.3 简单工厂模式

工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第7张图片

4.1.4 工厂模式

在《简单工厂模式》一节我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第8张图片

4.1.5 抽象工厂模式

抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第9张图片

4.1.6 建造者模式

建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第10张图片

4.2 结构型模式

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。
由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

4.2.1代理模式

代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第11张图片
代理模式的扩展:动态代理模式
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第12张图片

4.2.2适配器模式

适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
类适配器模式的结构图:
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第13张图片
对象适配器模式的结构图
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第14张图片
适配器模式(Adapter)可扩展为双向适配器模式:
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第15张图片

4.2.3 桥接(Bridge)模式

桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第16张图片
桥接模式模式的扩展:有时桥接(Bridge)模式可与适配器模式联合使用。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第17张图片

4.2.4装饰(Decorator)模式

装饰(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第18张图片
装饰模式的扩展:
装饰模式所包含的 4 个角色不是任何时候都要存在的,在有些应用环境下模式是可以简化的。
(1) 如果只有一个具体构件而没有抽象构件时,可以让抽象装饰继承具体构件,其结构图如图 4 所示。

六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第19张图片
(2) 如果只有一个具体装饰时,可以将抽象装饰和具体装饰合并,其结构图如图 5 所示。

六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第20张图片

4.2.5外观(Facade)模式

外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第21张图片
外观模式的扩展:在外观模式中,当增加或移除子系统时需要修改外观类,这违背了“开闭原则”。如果引入抽象外观类,则在一定程度上解决了该问题。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第22张图片

4.2.6 享元(Flyweight)模式

享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第23张图片
享元模式的扩展:
(1) 单纯享元模式,这种享元模式中的所有的具体享元类都是可以共享的,不存在非共享的具体享元类。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第24张图片
(2) 复合享元模式,这种享元模式中的有些享元对象是由一些单纯享元对象组合而成的,它们就是复合享元对象。虽然复合享元对象本身不能共享,但它们可以分解成单纯享元对象再被共享。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第25张图片

4.2.7 组合(Composite Pattern)模式

组合(Composite Pattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。
(1) 透明方式
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第26张图片
(2) 安全方式
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第27张图片

4.3行为型模式

行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

4.3.1模板方法(Template Method)模式

模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第28张图片
模式的扩展:在模板方法模式中,基本方法包含:抽象方法、具体方法和钩子方法,正确使用“钩子方法”可以使得子类控制父类的行为。如下面例子中,可以通过在具体子类中重写钩子方法 HookMethod1() 和 HookMethod2() 来改变抽象父类中的运行结果。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第29张图片

4.3.2策略(Strategy)模式

策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第30张图片
策略模式的扩展:
在一个使用策略模式的系统中,当存在的策略很多时,客户端管理所有策略算法将变得很复杂,如果在环境类中使用策略工厂模式来管理这些策略类将大大减少客户端的工作复杂度
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第31张图片

4.3.3命令(Command)模式

命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第32张图片
命令模式的扩展:在软件开发中,有时将命令模式与前面学的组合模式联合使用,这就构成了宏命令模式,也叫组合命令模式。宏命令包含了一组命令,它充当了具体命令与调用者的双重角色,执行它时将递归调用它所包含的所有命令。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第33张图片

4.3.4责任链(Chain of Responsibility)模式

责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第34张图片
模式的扩展:
职责链模式存在以下两种情况。

  • 纯的职责链模式:一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任);把责任推给下家处理。
  • 不纯的职责链模式:允许出现某一个具体处理者对象在承担了请求的一部分责任后又将剩余的责任传给下家的情况,且一个请求可以最终不被任何接收端对象所接收。
4.3.5状态(State)模式

状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第35张图片
状态模式的扩展:在有些情况下,可能有多个环境对象需要共享一组状态,这时需要引入享元模式,将这些具体状态对象放在集合中供程序共享
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第36张图片

4.3.6观察者(Observer)模式

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第37张图片
模式的扩展
在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

4.3.7中介者(Mediator)模式

中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第38张图片
模式的扩展
在实际开发中,通常采用以下两种方法来简化中介者模式,使开发变得更简单。

  1. 不定义中介者接口,把具体中介者对象实现成为单例。
  2. 同事对象不持有中介者,而是在需要的时候直接获取中介者对象并调用。
    六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第39张图片
4.3.8 迭代器(Iterator)模式

迭代器(Iterator)模式的定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第40张图片
模式的扩展:迭代器模式常常与组合模式结合起来使用,在对组合模式中的容器构件进行访问时,经常将迭代器潜藏在组合模式的容器构成类中。当然,也可以构造一个外部迭代器来对容器构件进行访问。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第41张图片

4.3.9访问者(Visitor)模式

访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第42张图片
模式的扩展:
访问者(Visitor)模式是使用频率较高的一种设计模式,它常常同以下两种设计模式联用。

(1)与“迭代器模式”联用。因为访问者模式中的“对象结构”是一个包含元素角色的容器,当访问者遍历容器中的所有元素时,常常要用迭代器。如【例1】中的对象结构是用 List 实现的,它通过 List 对象的 Iterator() 方法获取迭代器。如果对象结构中的聚合类没有提供迭代器,也可以用迭代器模式自定义一个。

(2)访问者(Visitor)模式同“组合模式”联用。因为访问者(Visitor)模式中的“元素对象”可能是叶子对象或者是容器对象,如果元素对象包含容器对象,就必须用到组合模式.
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第43张图片

4.3.10备忘录(Memento)模式

备忘录(Memento)模式的定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式.
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第44张图片
模式的扩展:
在前面介绍的备忘录模式中,有单状态备份的例子,也有多状态备份的例子。下面介绍备忘录模式如何同原型模式混合使用。在备忘录模式中,通过定义“备忘录”来备份“发起人”的信息,而原型模式的 clone() 方法具有自备份功能,所以,如果让发起人实现 Cloneable 接口就有备份自己的功能,这时可以删除备忘录类.
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第45张图片

4.3.11解释器(Interpreter)模式

解释器(Interpreter)模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
六.java进阶-Java设计模式:23种设计模式(GoF23)学习这一篇就够了(详细)_第46张图片

你可能感兴趣的:(java启蒙之路,java)