代码编织梦想

设计模式快速复习

Design Pattern Explanation with C++ Implementation(By K_Eckel) 的阅读总结

创建型模式

Factory :提供一个专门用来创建对象的工厂类,而不是直接使用 new ;

  • 可以根据运行时的情况来判断究竟是实例化谁,代码可读性强
  • 只能用于一类类(例如有一个共同的基类),腰围不同的类提供一个对象创建的结构,需要用到 AbstractFactory

请添加图片描述

AbstractFactory:用于创建一组相关或者相互依赖的对象,基于 Factory 实现

请添加图片描述

Singleton :创建一个全局唯一的变量,即使在纯面向对象范式的编程当中,也可以不借助全局变量来实现单例。

  • Singleton 不可以被实例化,而是直接调用其 getInstance( ) 等函数(往往是静态函数)来返回唯一实例
  • Singleton 经常和 Factory 一起使用,因为一般来说工厂对象只需要一个

请添加图片描述

Builder:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要将复杂对象的创建过程和这个对象的表示(展示)分离开来,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

  • Builder 的关键是 Director 对象并不直接返回对象,当然也可以提供一个默认的返回对象的接口(即返回通用的复杂对象的创建,即不指定或者特定唯一指定 BuildPart 中的参数)
  • Builder 和 AbstractFactory 很相似,都是用来创建大的复杂的对象。 Builder 强调一步一步创建对象,并且可以通过相同的创建过程可以获得不同的结果对象,并且不直接返回对象;AbstractFactory 强调的是为创建多个相互依赖的对象提供一个统一的接口。

请添加图片描述

Prototype 模式:新对象的创建可以通过已有对象进行创建,其他于语言常有 clone() 或 copy( ) 函数,在 C++ 中由拷贝构造函数来实现。

  • 这里 Prototype 本身就是对象工厂,与前面几个工厂不同,prototype 强调从自身复制自己创建新类。

请添加图片描述

结构型模式

Bridge:使用组合(委托)的方式将抽象和实现彻底地解耦,抽象和实现可以独立地变化,减少因为需求变化而导致类的迅速膨胀。

  • Bridge 的关键是在于 “favor composition over inheritance” ,即 pImpl 方法代替继承。

请添加图片描述

Adapter:转换器,我们已经实现的接口通过接口转换得到一个第三方的接口,例如 C++ 中的 stack 和 queue,实际上底层可以是 vector、list、deque 等;常有两种实现方法:类模式和对象模式,区别在于是 inheritance 还是 composition

请添加图片描述

请添加图片描述

Decorator:需要为一个已经定义好的类添加新的职责,但是又不想修改类,也不想继承某一个具体的类,就可以考虑使用 decorator;

  • 注意图示里的 Operation() 被装饰以后,我们调用 Operation 的同时也会执行 addedBehavior()
  • decorator 和 proxy 模式都会有一个指向其他对象的引用/指针,但 Proxy 模式会提供使用其作为代理的对象统一的接口,使用代理类将其操作都委托给 Proxy 直接进行,其实是组合和委托之间的微妙区别。

请添加图片描述

Composite:递归构建树状的组合结构(有点像广义表),每个 composite 里边可以有多个 component,每个 component 可以是具体的实现(如 Leaf),也可以是又一个 composite

  • Composite 和 Decorator 的模式结构图类似,但是 Composite 模式旨在构造类,而 Decorator 模式重在不生成子类即可给对象添加职责

(图里错了,leaf 右边的是 composite 类)

请添加图片描述

Flyweight :将对象的状态分为内部状态和外部状态,内部状态可以被共享、不会变化,存储在对象中;而外部状态可以适当的时候作为参数传递给对象。

  • 例如一个字母“a”在文档中出现了若干次,可以让这些字符共享“a”一个对象,其字体大小等可以作为参数传入。
  • Flyweight 模式在实现过程中主要是要为共享对象提供一个存放的“仓库”(对象池),我觉得有点像 Java 处理 String 的方式,上面的解释反而使得 Flyweight 的意思更抽象了hhh

请添加图片描述

Facade :就有点像是我们要完成一件事情,这个事情由不同的步骤组成,而这些步骤的实现方法都分布在不同的类中,那么我们可以写一个类,将各个类都包裹起来,然后只对外维护一个接口,这样我们只需要调用这个接口,内部就可以自动地调用其他类的方法依次完成这件事情。

  • Facade 在高层提供了一个统一的接口,解耦了系统

请添加图片描述

Proxy: 以下问题适合使用 Proxy 模式

  • 创建开销大的对象时,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成
  • 为网络上的对象创建一个局部的本地代理,我们将这个操纵的过程交给一个代理去完成
  • 对对象进行控制访问的时候,比如论坛上不同权限的用户,将这个工作交给一个代理去完成
  • 智能指针

Proxy 模式最大的好处就是实现了逻辑和实现的彻底解耦

请添加图片描述

行为模式

Template :采用继承的方法,将某一处理问题的逻辑框架放在抽象基类中,并且定义好细节的接口,而在子类中实现每一个步骤的实现细节。

  • 本质上就是使用多态的方法实现算法实现细节和高层接口的松耦合。(想一下侯捷大佬举的操作系统的例子)

  • Template 模式体现了 DIP(依赖倒置原则),其含义就是父类调用子类的操作。

  • 相比于 Strategy,Template 的问题就是继承固有的问题,但相应地 Strategy 付出了空间和时间上的代价

请添加图片描述

Strategy:Strategy 要解决的问题和 Template 是一样的,但是逻辑被封装到 Context 类里(而 Template 的逻辑封装在 AbstractClass 里),通过组合的方式将具体算法的实现在组合对象中实现

  • Strategy 模式和 Template 模式实际是实现一个抽象接口的两种方式:继承和组合之间的区别,但还是优先使用组合
  • Strategy 模式很 State 模式也有相似之处,但是 State 模式注重的对象在不同的状态下不同的操作。两者之间的区别就是 State 模式中具体实现类中有对 Context 的函数的引用,而 Strategy 模式则没有。

请添加图片描述

组合

  • 优点
    1. “黑盒”复用,因为被包含对象的内部细节对外是不可见的;
    2. 封装性好,原因为 1.;
    3. 实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性小);
    4. 可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象基类的指针)。
  • 缺点
    1. 系统中对象过多。

继承

  • 优点
    1. 易于修改和扩展那些被复用的实现。
  • 缺点
    1. 破坏了封装性,继承中父类的实现细节暴露给子类了;
    2. “白盒”复用,原因在 1. 中;
    3. 当父类的实现更改时,其所有子类将不得不随之改变
    4. 从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)。

State:需要对不同的状态作出不同的响应,同时分离状态逻辑和动作(而不是像 switch-case 一样全部写在一起)

  • 将 State 声明为 Context 的友元类(friend class),这样才可以切换状态
  • State 及其子类中的操作都将 Context*传入作为参数(传入 this 指针)

请添加图片描述

Observer:MVC 就是一种 Observer 模式,发布-订阅,目标是通知的发布者,观察者是通知的订阅者

  • Subject 中有一个保存指向 Observer 引用的数组,可以发布消息,调用每个 Oberver 的 update

请添加图片描述

Memento:不破坏封装性的前提下,捕获并保存一个类的内部状态,这样就可以利用保存的状态实施恢复操作(撤销/Undo 的动作)

  • Memento 模式的关键就是 friend class Originator,并且 Memento 的接口都设为 private ,这样 Originator 就可以访问到所有东西,保证了封装性
  • Memento 相当于是 Originator 的一个备份
  • 在 Command 模式中,Memento 模式经常被用来维护可以撤销操作的状态

请添加图片描述

Mediator :将对象间的交互和通讯封装在一个类中,个对象间的通信不用显示声明引用,大大降低了系统的复杂性能,带来了系统对象间的松耦合。

  • 每个 Colleague 维护一个 Mediator,将多对多的通信转化为一对多的通信;A、B 和 Mediator 之间需要双向绑定

请添加图片描述

Command:将请求封装到一个对象(Command)中,并将请求的接收者存放到具体的 ConcreteCommand 类中(Receiver),从而实现调用操作的对象和操作的具体实现者之间的解耦。

  • Command 类中一般就是只是一些接口的集合,并不包含任何的数据属性
  • 在 Command 要增加新的处理操作对象很容易,我们可以通过创建新的继承自 Command 的子类来实现这一点。
  • Command 模式可以和 Memento 模式结合起来,支持取消的操作

请添加图片描述

Visitor:在面对需求更新时,将更新封装到一个类中(访问操作),并由待更改类提供一个接受接口

  • 这里 Element 是待更改的类,Visitor 是更新的内容
  • Visitor 的关键是双分派,双分派意味着执行的操作将取决于请求的种类和接收者的类型;而 C++ 是单分派,可以通过 RTTI 来实现
  • 问题:破坏了封装性,从外部可以修改 Element 对象的状态,要不然就要 Element 提供足够的 public 接口,要不然要声明 friend Visitor;ConcreteElement 的扩展很困难,每增加一个 Element 的子类,就要增加 Visitor 的接口

请添加图片描述

Chain of Responsibility:将可能处理一个请求的对象链成一个链,并且将请求在链上传递,直到有对象处理该请求(可能需要提供一个默认处理所有请求的类)

  • 这里 Handler 可以相互链接成链表,每次接到请求首先看看自己可不可以处理,如果不行,就交给后继节点处理
  • Chain of Responsibility 模式的最大的一个有点就是给系统降低了耦合,请求的发送者完全不必知道该请求会被哪个应答对象处理

请添加图片描述

Iterator:将一个聚合对象的遍历问题封装到一个类中进行,避免暴露这个聚合对象的内部表示,比如 C++ 容器的迭代器

  • 为了更好地保护 Aggregate 的状态,可以尽可能减少它的 public 接口,而通过将 Iterator 对象声明为 Aggregate 的友元来给予Iterator一些特权,获得访问 Aggregate 私有数据和方法的机会

请添加图片描述

Interpreter:使用一个解释器,为用户提供一个一门定义语言语法表示的解释器,然后通过这个解释器来解释语言中的句子。(可以想想编译器的前端)

  • Interpreter 模式中使用类来表示文法规则,因此可以很容易实现文法的扩展,可以使用 Flyweight 模式来实现终结符的共享

请添加图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Ryansior/article/details/129678639

软件设计师复习资料_weixin_44304265的博客-爱代码爱编程

从大禹治水看构件与集成 大禹治水   在远古的尧、舜时代,黄河流域经常发生了大水灾,洪水横流,五谷不收,家破人亡。所以尧派鲧去治水,鲧沿用了过去的传统法子,水来土挡,用土筑堤,堵塞漏洞。但由于洪水凶猛,不断冲击土墙,结果弄

java复习快速导航_慢慢慢时光的博客-爱代码爱编程

不定期更新,希望不断完善自己的java地图,欢迎小伙伴一起温故知新,早日进大厂 1. java基础 java基础必背知识点 java基础加强知识点 javaweb1 (mysql、HTML、js、xml)

韩顺平图解java设计模式_嘟爷java超神学堂的博客-爱代码爱编程

今天分享一部设计模式相关的视频,好好复习帮助还是很大的。 课程介绍 1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑 2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支

Java中的设计模式和算法-爱代码爱编程

今天内容: (1)常用的设计原则 (2)常用的设计模式 (3)常用的查找算法 (4)常用的排序算法 1.常用的设计原则(记住) 1.1 软件开发的流程 需求分析文档 => 概要设计文档 => 详细设计文档 => 编码和测试 => 安装和调试 => 维护和升级 1.2 常用的设计原则 开闭原则 - 对扩展开放,

如何才能真正的学会设计模式-爱代码爱编程

        设计模式算是一个优秀程序员的必修课。我承认一个程序员不懂设计模式,也可以完成大多数的日常任务。但是你写的代码也仅仅是完成任务了而已,当面临需求的更改,后期维护时你会发现糟糕的设计会让你痛苦不堪。良好的模块设计,可以让系统看上去更优雅,后期的维护和扩展也会更方便。我承认有些朋友没有学过任何模式,也能写出优雅的代码,但那一定是建立在他阅读了大量

软件设计模式期末复习-爱代码爱编程

一、UML 1、聚合(contains空心菱形) 整体与部分的关系(部分脱离整体可独立存在)。Java代码:部分对象可为整体类中的构造、set方法的参数 public class Car { private Engine engine; public void Car(Engine engine){ this.engi

设计模式之c++建造者模式(示例代码)-爱代码爱编程

建造者模式(Builder Pattern)是一种创建型设计模式,用于将一个复杂对象的构建过程和表示分离,使得同样的构建过程可以创建不同的表示。 在 C++ 中实现建造者模式,通常需要定义一个抽象的建造者接口和具体的建造者

设计模式考题复习-爱代码爱编程

一.定义 设计模式六大基本原则: 单一职责原则:一个类或者一个方法只负责一项职责,尽量做到类的只有一个行为原因引起变化;里氏替换原则:能出现子类的地方都应该可以允许父类出现,也就是子类可以扩展父类的功能,而不能改变原有父

设计模式复习一_某信息咨询公司推出收费的在线商业信息查询模块,需要对查询用户进行身份验证并记-爱代码爱编程

设计模式 一、创建型模式 创建型模式(Creational Pattern)对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共同的接口,而不

设计模式——单例模式解析-爱代码爱编程

0.前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦~ 1.单例模式介绍 单例模式定义: 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 单例模式的使用场景/优