五万字详解“GoF”的23种设计模式

news2024/11/18 7:35:48

大家好,我是栗筝i,近期我总结梳理了 “GoF”的 23 种设计模式,并使用 Java 对每种设计模式都进行了伪代码与 Demo 实现,并总结了每种设计模式的应用场景,优缺点,UML图等相关内容,字/词数达到了5万,希望对大家有所帮助~~

更多 Java 相关内容,大家可以浏览:全网最全的 Java 技术栈内容梳理(持续更新中)

Ps:大家还可以加入我的社区:栗筝i的社区,在更新上我将尽量保证文章的高频、高质、高量,希望大家积极交流监督,让我们共同进步。


文章目录

    • 一、设计模式概念
        • 1、Got 的 23 种设计模式
        • 2、设计模式介绍
        • 3、设计模式分类
        • 4、设计模式思维导图
    • 二、设计模式原则
        • 1、开闭原则
        • 2、里氏替换原则
        • 3、依赖倒置原则
        • 4、单一职责原则
        • 5、接口隔离原则
        • 5、迪米特法则
        • 7、合成复用原则
    • 三、创建型设计模式
        • 1、工厂方法模式
        • 2、抽象工厂模式
        • 3、单例模式
        • 4、建造者模式
        • 5、原型模式
    • 四、结构型设计模式
        • 1、适配器模式
        • 2、装饰器模式
        • 3、代理模式
        • 4、外观模式
        • 5、桥接模式
        • 6、组合模式
        • 7、享元模式
    • 五、行为型设计模式
        • 1、策略模式
        • 2、观察者模式
        • 3、模板方法模式
        • 4、迭代器模式
        • 5、责任链模式
        • 6、命令模式
        • 7、备忘录模式
        • 8、状态模式
        • 9、访问者模式
        • 10、中介者模式
        • 11、解释器模式
    • 六、设计模式总结


一、设计模式概念

1、Got 的 23 种设计模式

1995 年,GoF(Gang of Four,四人组,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人组成)合作出版了 **《Design Patterns: Elements of Reusable Object-Oriented Software》 **一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称【GoF设计模式】。

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

2、设计模式介绍

设计模式(Design pattern):是软件开发经验的总结,是软件设计中常见问题的典型解决方案。每个模式都像一个蓝图,您可以自定义以解决代码中的特定设计问题。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

3、设计模式分类

设计模式共分为 3 类模式, 分别为:创建型模式,结构型模式,行为型模式。

  • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式;

  • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式;

  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

实际上,设计模式要干的事情就是解耦。创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦,在下面我们会分别进行详细的介绍。

其中又分为:

  • 接口适配:适配器、外观、桥接模式
  • 行为扩展:装饰模式
  • 性能与对象访问:代理、享元模式
  • 抽象集合:组合模式
  • 算法封装:模板方法、策略、命令模式
  • 对象去耦:中介、观察者模式
  • 抽象集合:迭代器模式
  • 行为扩展:访问者、责任链模式
  • 对象状态:状态模式

4、设计模式思维导图

image-20221205000859076


二、设计模式原则

设计模式有 7 大原则,目的只有一个:降低对象之间的耦合,增加程序的可复用性、可扩展性和可维护性。

设计原则归纳目的
开闭原则对扩展开放,对修改关闭降低维护带来的新风险
里氏替换原则不要破坏继承体系,子类重写方法功能发生改变,不应该影响父类方法的含义防止继承泛滥
依赖倒置原则高层不应该依赖低层,要面向接口编程更利于代码结构的升级扩展
单一职责原则一个类只干一件事,实现类要单一便于理解,提高代码的可读性
接口隔离原则一个接口只干一件事,接口要精简单一功能解耦,高聚合、低耦合
迪米特法则不该知道的不要知道,一个类应该保持对其它对象最少的了解,降低耦合度只和朋友交流,不和陌生人说话,减少代码臃肿
合成复用原则尽量使用组合或者聚合关系实现代码复用,少使用继承降低代码耦合

1、开闭原则

开闭原则(Open Closed Principle,OCP):软件实体应当对扩展开放,对修改关闭。

实现方法: 通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。

2、里氏替换原则

里氏替换原则(Liskov Substitution Principle,LSP):继承必须确保超类所拥有的性质在子类中仍然成立。

里氏替换原则是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

对里氏替换原则的定义可以总结如下 4 点:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
  • 子类中可以增加自己特有的方法;
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松;
  • 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等。

3、依赖倒置原则

依赖倒置原则(Dependence Inversion Principle,DIP)有 2条 原则:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;

  • 抽象不应该依赖细节,细节应该依赖抽象。

核心思想是:要面向接口编程,不要面向实现编程, 降低类间的耦合性。

依赖倒置原则的主要作用如下:

  • 依赖倒置原则可以降低类间的耦合性;
  • 依赖倒置原则可以提高系统的稳定性;
  • 依赖倒置原则可以减少并行开发引起的风险;
  • 依赖倒置原则可以提高代码的可读性和可维护性。

依赖倒置原则的实现方法:

  • 每个类尽量提供接口或抽象类,或者两者都具备;
  • 变量的声明类型尽量是接口或者是抽象类;
  • 任何类都不应该从具体类派生;
  • 使用继承时尽量遵循里氏替换原则。

4、单一职责原则

单一职责原则(Single Responsibility Principle,SRP)单一功能原则:规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。

5、接口隔离原则

接口隔离原则(Interface Segregation Principle,ISP)要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。

接口隔离原则定义:客户端不应该被迫依赖于它不使用的方法,一个类对另一个类的依赖应该建立在最小的接口上。

接口隔离原则的实现方法,在具体应用接口隔离原则时,应该根据以下几个规则来衡量:

  • 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑;
  • 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法;
  • 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑;
  • 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

5、迪米特法则

迪米特法则(Law of Demeter,LoD)又叫作最少知识原则,只与你的直接朋友交谈,不跟“陌生人”说话。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

迪米特法则中的“朋友”是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

在运用迪米特法则时要注意以下 6 点:

  • 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标;
  • 在类的结构设计上,尽量降低类成员的访问权限;
  • 在类的设计上,优先考虑将一个类设置成不变类;
  • 在对其他类的引用上,将引用其他对象的次数降到最低;
  • 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法);
  • 谨慎使用序列化(Serializable)功能。

7、合成复用原则

合成复用原则(Composite Reuse Principle,CRP)又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范


三、创建型设计模式

1、工厂方法模式

工厂方法是一种十分常用的创建型设计模式,它在父类中提供了创建对象的接口但允许子类更改将要创建的对象的类型。

在一些情况下,要创建的对象需要一系列复杂的初始化操作,比如查配置文件、查数据库表、初始化成员对象等,如果把这些逻辑放在构造函数中,会极大影响代码的可读性。不妨定义一个类来专门负责对象的创建,这样的类就是工厂类,这种做法就是工厂模式,在任何需要生成复杂对象的地方,都可以使用工厂模式。

一般情况下,我们所提及的 “工厂模式” 会被细分为三种,即简单工厂、工厂方法和抽象工厂。而 《GoF 的设计模式》一书中,它将简单工厂模式看作是工厂方法模式的一种特例,所以工厂模式只被分成了工厂方法和抽象工厂两类。

# 关于 简单工厂模式

简单工厂模式(Smiple Factory Pattern):定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类,简单工厂模式也被称为静态工厂模式。

简单工厂模式将产品的“消费”和“生产”完全分开,调用房,只需要自己需要什么产品,和如何使用就可以了,而对于产品的具体生产任务,则由工厂类来实现。

简单工厂模式的详细内容可以参照:【详解设计模式-简单工厂模式 : https://lizhengi.blog.csdn.net/article/details/128043083】

# 关于 工厂方法模式

工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过工厂父类定义负责创建产品的公共接口,子类负责生产具体对象。可以理解为简单工程模式的升级,解决简单工厂模式的弊端。

如果在简单工厂模式中,扩增具体产品信息,需要对原有工厂进行改造,当需求的产品类别增加到一定程度时,工厂较负责的产品线也相对复杂,当出现问题时,所有的产品的生产将会中断。工厂方法模式 解决简单工厂模式的弊端,实现父类定义公共实现接口,子类负责实现创建具体的对象,这样就可以实现增加产品类时,不需要修改工厂类,而只需要修改工厂子类。

image-20221204235642566

工厂方法模式的详细内容可以参照:【详解设计模式-工厂方法模式 : https://lizhengi.blog.csdn.net/article/details/128050174】

2、抽象工厂模式

抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。这里的抽象角色就是产品族。Ps:产品族是具有相同属性的同类型产品。

抽象工厂,非常适合解决两个维度的组合产品的构造问题,取其中一个维度作为产品族,另外一个维度作为产品族中具体的多个产品。

抽象工厂模式的详细内容可以参照:【详解设计模式-抽象工厂模式 : https://lizhengi.blog.csdn.net/article/details/128055856】

3、单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在单例模式中,内存中只会创建且仅创建一次对象在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。

Ps:在 Spring 中,每个 Bean 默认就是单例的,这样的优点是 Spring 容器可以管理这些 Bean 的生命周期,决定什么时候创建出来,什么时候销毁,销毁的时候如何处理等等。

单例模式有两种类型:

  • 懒汉式:在真正需要使用对象时才去创建该单例类对象。在开发中如果对内存要求非常高,那么使用懒汉式写法,可以在特定时候才创建该对象;
  • 饿汉式:在类加载时已经创建好该单例对象,等待被程序使用。如果对内存要求不高使用饿汉式写法,因为简单不易出错,且没有任何并发安全和性能问题。

单例模式的详细内容可以参照:【详解设计模式-单例模式 : https://lizhengi.blog.csdn.net/article/details/128061347】

4、建造者模式

建造者模式(Builder Pattern)也叫做生成器模式,是 GoF 的 23 种设计模式的一种,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

当我们需要实列化一个复杂的类,以得到不同结构类型和不同的内部状态的对象时,我们可以用不同的类对它们的实列化操作逻辑分别进行封装,这些类我们就称之为建造者。

当我们需要来自同一个类,但是要就有不同结构对象时,就可以通过构造另一个建造者来进行实列化。

建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。

  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的;
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

建造者模式的详细内容可以参照:【详解设计模式-建造者模式 : https://lizhengi.blog.csdn.net/article/details/128067131】

5、原型模式

原型模式(Prototype Pattern) ,是 GoF 的 23 种设计模式的一种,是用于创建重复的对象,同时又能保证性能。属于创建型模式,提供创建对象的最佳方式。

原型(Prototype),在制造业中通常是指大批量生产开始之前研发出的概念模型,并基于各种参数指标对其进行检验,如果达到了质量要求,即可参照这个原型进行批量生产。原型模式达到以原型实例创建副本实例的目的即可,并不需要知道其原始类,也就是说,原型模式可以用对象创建对象,而不是用类创建对象,以此达到效率的提升。

原型模式的使用需要注意浅拷贝与深拷贝的问题:

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址;
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

原型模式的详细内容可以参照:【详解设计模式-原型模式 : https://lizhengi.blog.csdn.net/article/details/128075439】


四、结构型设计模式

1、适配器模式

适配器模式(Adapter Pattern)又称为变压器模式,是 GoF 的 23 种设计模式中的一种结构型设计模式。

适配器模式 的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。

image-20221204235630037

适配器模式的详细内容可以参照:【详解设计模式-适配器模式 : https://lizhengi.blog.csdn.net/article/details/128085445】

2、装饰器模式

装饰器模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),是 GoF 的 23 种设计模式中的一种结构型设计模式。

装饰器模式 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。

装饰器模式 的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能

装饰器模式的详细内容可以参照:【详解设计模式-装饰器模式 : https://lizhengi.blog.csdn.net/article/details/128092556】

3、代理模式

代理模式(Proxy Pattern),Java 常见的设计模式之一,是 GoF 的 23 种设计模式中的一种结构型设计模式。

代理模式 是指客户端并不直接调用实际的对象,而是通过调用代理对象,来间接的调用实际的对象。代理对象 具备真实对象的功能,并代替真实对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理(为真实对象提供代理,然后供其他对象通过代理访问真实对象)。

image-20221204235614995

代理模式的详细内容可以参照:【详解设计模式-代理模式 : https://lizhengi.blog.csdn.net/article/details/128103046】

4、外观模式

外观模式(Facade Pattern),又称为门面模式,是 GoF 的 23 种设计模式中的一种结构型设计模式。

外观模式 是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通过外观类来调用内部子系统中方法,从而外观模式让客户和子系统之间避免了紧耦合。

外观模式 的本质是:封装交互,简化调用。

外观模式的详细内容可以参照:【详解设计模式-外观模式 : https://lizhengi.blog.csdn.net/article/details/128110295】

5、桥接模式

桥接模式(Bridge Pattern)也称为桥梁模式、接口模式或者柄体模式,有点像适配器模式,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

桥接模式 是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

桥接模式的详细内容可以参照:【详解设计模式-桥接模式 : https://lizhengi.blog.csdn.net/article/details/128119591】

6、组合模式

组合模式(Composite Pattern),又叫部分整体模式,是 GoF 的 23 种设计模式中的一种结构型设计模式。

组合模式 是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。它创建了对象组的树形结构。

组合模式的详细内容可以参照:【详解设计模式-组合模式 : https://lizhengi.blog.csdn.net/article/details/128127215】

7、享元模式

享元模式(Flyweight Pattern),是对象池的一种体现,也是 GoF 的 23 种设计模式中的一种结构型设计模式。

享元模式 主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

享元模式的详细内容可以参照:【详解设计模式-享元模式 : https://lizhengi.blog.csdn.net/article/details/128136268】


五、行为型设计模式

1、策略模式

策略模式(Strategy Pattern)也被称为政策模式(Policy Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

策略模式 是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,使得它们可以互换,被封装起来的算法具有独立性外部不可改变其特性。

策略模式 在实际的项目开发中,这个模式也比较常用。最常见的应用场景是,利用它来避免冗长的 if-else 或 switch 分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。

image-20221204235550652

策略模式的详细内容可以参照:【详解设计模式-策略模式 : https://lizhengi.blog.csdn.net/article/details/128143313】

2、观察者模式

观察者模式(Observer Pattern)也被称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式,是在 GoF 23 种设计模式中定义了的行为型模式。

观察者模式 定义了一对多的关系,让多个观察者对象同时监听某一个主体对象,这个主体对象发生变化时就会通知所有的观察者对象,使得他们能够自己更新自己。

image-20221204235534426

观察者模式的特点:

  1. 被观察者不知道具体的观察者是谁,只知道自己被观察了,并且在合适的时机进行广播,让感兴趣的观察者知道发生了什么事情;

  2. 观察者依赖于被观察者,被观察者不依赖于观察者,是单向关系,耦合程度不高。没有被观察者,观察者无法工作;没有观察者,被观察者该干啥干啥,因为被观察者本来就不清楚谁观察他,发广播是被观察的个人行为;

  3. 通常被观察者出现行为上的变化,需要观察者做出反馈。显然一般情况下观察者并不知道被观察者啥时候会有变化,因此该反馈是一种被动反馈,实现的是一种回调机制。

观察者模式的详细内容可以参照:【详解设计模式-观察者模式 : https://lizhengi.blog.csdn.net/article/details/128152116】

3、模板方法模式

模板方法模式(Template Method Pattern)也被称为模板模式(Template Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

模板方法模式 定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法模式 核心:处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定。因此,我们采用模版方法模式,将这个节点的代码实现转移给子类完成。即:处理步骤在父类中定义好,具体的实现延迟到子类中定义

模板方法模式的详细内容可以参照:【详解设计模式-模板方法模式 : https://lizhengi.blog.csdn.net/article/details/128159860】

4、迭代器模式

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

迭代器模式 提供一种方法顺序访问一个聚合(指一组对象的组合结构,如:Java中的集合、数组等)对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的本质:控制访问聚合对象中的元素。其设计意图:无须暴露聚合对象的内部实现,就能够访问到聚合对象中的各个元素。

迭代器模式的详细内容可以参照:【详解设计模式-迭代器模式 : https://lizhengi.blog.csdn.net/article/details/128164451】

5、责任链模式

首先它可以对同一模块中有先后执行顺序要求的类或对象进行成链,以达到高聚合的目的。同时对于单一执行状态下的执行步骤,可以通过非状态模式的成链方式进行组装,便可以实现改变执行顺序的目的,让代码维护性变高。

责任链模式(Chain of Responsibility Pattern)也被称为职责链模式,是在 GoF 23 种设计模式中定义了的行为型模式。

责任链模式 是将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。当一个请求从链式的首段发出时,会沿着链的路径依此传递给每一个节点对象,直至有对象处理这个请求为止。

责任链模式 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。

责任链模式的详细内容可以参照:【详解设计模式-责任链模式 : https://lizhengi.blog.csdn.net/article/details/128171017】

6、命令模式

命令模式(Command Pattern)也被称为行动模式(Action Pattern)、事物模式(Transaction Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

命令模式 是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方。

命令模式的详细内容可以参照:【详解设计模式-命令模式 : https://lizhengi.blog.csdn.net/article/details/128176316】

7、备忘录模式

备忘录模式(Memento Pattern)也被称为快照模式(Snapshot Pattern)、Token 模式(Token Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

备忘录模式 会保存一个对象的某个状态,以便在适当的时候恢复对象。

备忘录模式 在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

备忘录模式的详细内容可以参照:【详解设计模式-备忘录模式 : https://lizhengi.blog.csdn.net/article/details/128181875】

8、状态模式

状态模式(State Pattern)也被称为状态机模式(State Machine Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

在状态模式 类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。状态模式 对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

状态模式的详细内容可以参照:【详解设计模式-状态模式 : https://lizhengi.blog.csdn.net/article/details/128191135】

9、访问者模式

访问者模式(Visitor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。据《大话设计模式》中说算是最复杂也是最难以理解的一种模式了。

访问者模式 是一种将数据操作与数据结构分离的设计模式,它可以算是 23 中设计模式中最复杂的一个,但它的使用频率并不是很高,大多数情况下,你并不需要使用访问者模式,但是当你一旦需要使用它时,那你就是需要使用它了。

访问者模式 的基本想法是,软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个 accept 方法用来接受访问者对象的访问。访问者是一个接口,它拥有一个 visit 方法,这个方法对访问到的对象结构中不同类型的元素做出不同的处理。在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施 accept 方法,在每一个元素的 accept 方法中会调用访问者的 visit 方法,从而使访问者得以处理对象结构的每一个元素,我们可以针对对象结构设计不同的访问者类来完成不同的操作,达到区别对待的效果。

image-20221204222000578

访问者模式 适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。

访问者模式的详细内容可以参照:【详解设计模式-访问者模式 : https://lizhengi.blog.csdn.net/article/details/128197861】

10、中介者模式

中介者模式(Mediator Pattern)也被称为调停者模式,是在 GoF 23 种设计模式中定义了的行为型模式。

中介者模式 是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。

中介者模式 的核心在于中介者类的引入,在中介者模式中,中介者类承担了两方面的职责 (所有对象之间的交互都 在 Mediator 类中进行):

  • 中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。该中转作用属于中介者在结构上的支持。
  • 协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致的和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。

中介者模式的详细内容可以参照:【详解设计模式-中介者模式 : https://lizhengi.blog.csdn.net/article/details/128208282】

11、解释器模式

解释器模式(interpreter pattern),是在 GoF 23 种设计模式中定义了的行为型模式。

解释器模式 这种模式被用在 SQL 解析、符号处理引擎等。

解释器模式 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。

image-20221204212444708

解释器模式的详细内容可以参照:【详解设计模式-解释器模式 : https://lizhengi.blog.csdn.net/article/details/128213942】


六、设计模式总结

设计模式是针对软件开发中经常遇到的一些设计问题,总结出来的一套解决方案或者设计思路。我们用设计原则来评判代码设计哪里有问题,然后再通过具体的设计模式来改善。

设计模式的目的是为了代码更加的优雅、易维护、易扩展

设计模式相较于其他的知识,是稍微简单易学的,但是也十分容易被滥用(应用设计模式会提高代码的可扩展性,但同时也会带来代码可读性的降低),因此我们需要注意的是,有些场景十分真的需要使用一些设计模式,而不是使它们被过度滥用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java中的String

/*** 关于java.lang.String类* 1、String表示字符串类型,属于引用数据类型,不属于基本数据类型* 2、在java中用双引号括起来的都是String对象* 3、java中规定,字符串是不可变的* 4、字符串存储在方法区的字符串常量池当中*/ …

单例模式(python)

一、模式定义 1. 单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 2. 单例模式的要点有三个: 某个类只能有一个实例 必须自…

[激光原理与应用-41]:《光电检测技术-8》- 白光干涉仪

目录 第1章 白光干涉仪概述 第2章 常见干涉仪 2.1 激光量块干涉仪 2.2 白光干涉测量表面形貌的系统 第1章 白光干涉仪概述 用于光在两个不同表面反射后形成的干涉条纹进行分析的设备。 干涉仪是一种对光在两个不同表面反射后形成的干涉条纹进行分析的仪器。 其基本原理就…

SpringColud——Ribbon(负载均衡)Hystrix(熔断器)

目录 1、Ribbon 1.1、什么是Ribbon(负载均衡) 1.2、创建两个user-service实例 1.3、开启负载均衡 2、Histrix(熔断器) 2.1、什么是Histrix 2.2、雪崩问题 2.3、服务降级 2.4、开启熔断 2.5、编写降级逻辑 2.6、编写降级…

顶象App加固——助力微投证券融入IOS生态

过去十年里,App几乎重新定义了互联网,如今所有人的智能手机里都有着无数个App。 以App store 为例。最新数据显示,当前61个国家/地区在 App Store 现存的App总数为29,085,727。其中虽包含重复的App,但也可见在不同国家/地区&…

毕业设计 基于STM32单片机的老人防摔倒报警系统 - 物联网 嵌入式

文章目录0 前言1 整体设计2 硬件电路3 软件设计4 跌倒检测算法5 关键代码6 最后0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉…

Partition of an interval

In mathematics, a partition of an interval [a, b] on the real line is a finite sequence x0, x1, x2, …, xn of real numbers such that a x0 < x1 < x2 < … < xn b. In other terms, a partition of a compact interval I is a strictly increasing seq…

《小白WEB安全入门》01. 扫盲篇

扫盲篇基础知识什么是WEB什么是前端什么是后端什么是数据库什么是协议什么是WEB安全什么是服务器什么是IP地址、端口什么是局域网、广域网、内网、外网什么是URL什么是MAC地址什么是&#xff08;端口&#xff09;映射什么是域名、DNS什么是网卡、网关什么是IPv4/IPv6什么是Linu…

51单片机的温控风扇设计

一.硬件方案 系统采用51单片机作为控制平台对风扇转速进行控制。可由用户设置高、低温度值&#xff0c;测得温度值在高低温度之间时打开风扇弱风档&#xff0c;当温度升高超过所设定的温度时自动切换到大风档&#xff0c;当温度小于所设定的温度时自动关闭风扇。风扇控制状态随…

论坛系统设计与实现

摘 要 网络技术的快速发展给各行各业带来了很大的突破&#xff0c;也给各行各业提供了一种新的管理模块&#xff0c;对于论坛交流将是又一个传统管理到智能化信息管理的改革&#xff0c;设计论坛系统设计与实现的目的就是借助计算机让复杂的论坛交流操作变简单&#xff0c;变…

第8部分 帧中继

帧中继线路是中小企业常用的广域网线路&#xff0c;其通信费用较低。由于帧中继技术的一些特殊性使得帧中继的配置较为复杂&#xff0c;特别是在帧中继上运行路由协议时更是如此。作为入门&#xff0c;对帧中继的理解应着重放在DLCI、PVC、帧中继映射和子接口等概念上。本章通过…

Redis--高级篇 D5 多级缓存(JVM进程缓存、Lua语法、OpenResty安装(通过lua扩展nginx))

1、JVM进程缓存 1.1 导入商品查询案例 案例导入说明 为了演示多级缓存&#xff0c;我们先导入一个商品管理的案例&#xff0c;其中包含商品的CRUD功能。我们将来会给查询商品添加多级缓存。 1.安装MySQL 后期做数据同步需要用到MySQL的主从功能&#xff0c;所以需要大家在虚…

【Pytorch】.item() 方法介绍

文章目录一、.item() 方法介绍1. 方法介绍2. 那么有什么用呢&#xff1f;二、实例参考链接一、.item() 方法介绍 1. 方法介绍 我们先看官网中是怎么介绍的&#xff1a; 返回这个张量的值作为一个标准的Python数字。 详情页中说&#xff1a; # TORCH.TENSOR.ITEM Tensor.ite…

配对交易之统计套利配对:模型的应用

接下来&#xff0c;介绍把协整模型应用到取对数之后的股价上面。 前提假设&#xff1a;股价取对数之后是一个随机游走过程&#xff0c;即非平稳的。 现在有股票A和B,股价取对数之后的两个时间序列是以及。使用误差修正的表达方式&#xff1a; 能够唯一确定以上式子的参数是协…

uView教程-抽屉菜单 #低代码 #小程序 #uView

这种抽屉效果是如何制作的呢&#xff1f; 在guiplan低代码开发工具中&#xff0c; 点击"uView框架", 输入关键字"弹出层"进行搜索&#xff0c; 找到"带用户菜单" 点击"一键插入", 这我们一个抽屉菜单就插入进来了&#xff0c; 底部…

MapReduce编程实例-词频统计实现

文章目录词频统计实现思路词频统计实现步骤1. 准备数据文件1.1 在虚拟机上创建文本文件1.2 上传文件到HDFS指定目录2. 创建Maven项目3. 添加相关依赖4. 创建日志属性文件5. 创建词频统计映射类6. 创建词频统计驱动器类7. 运行词频统计驱动器类&#xff0c;查看结果8. 修改词频统…

设计一个简单HTML爵士音乐网页(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

SpringCloud Feing 源码 (简单实用) (一)

文章目录1.远程调用2.代码解析2.1 Eureka微服务2.1 微服务结构以及配置类2.2 公共类2.3 provider微服务2.4 Feign-Order微服务3.结果展示1.远程调用 本地过程调用&#xff08;Local Procedure Call&#xff0c;LPC&#xff09;&#xff0c;是指同一台机器上运行的不同进程之间…

从MES到MOM,抓住中国工业软件的机遇

从全球市场看&#xff0c;MES也是正进入MOM阶段&#xff0c;如图四所示。目前很多还是智能化第二代MES&#xff0c;主要是加强数据记录与处理和设备自动化管理&#xff0c;通过更精确的过程状态跟踪和更完整的数据记录&#xff0c;获取更多的数据来优化生产管理&#xff0c;并通…

被微服务轰炸?莫怕!耗时35天整出的「微服务学习教程」送你

又被微服务轰炸&#xff1f;莫慌莫怕&#xff01;小编连续25天&#xff0c;整出这份最新最全「学习教程」送你&#xff01; 微服务架构学习教程&#xff1a;RPCDubboSpirngBootSpringCloud AlibabaDockerK8s 手绘了整个微服务架构的知识体系脑图&#xff0c;还有针对分部的Dub…