一句话总结GoF 23种设计模式

2024-03-25 07:58

本文主要是介绍一句话总结GoF 23种设计模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以GoF的经典教材为例,一句话总结个人的理解。

OO回顾

  • 四大概念
    • 抽象:抽象为了简化问题,简单即美,相信我,人类很笨
    • 继承:为了便于扩展或改写原有的功能
    • 多态:为了便于改写原有的功能
    • 封装:组件化,便于理解、替换与复用,因此系统会更加灵活(后文提到封装XXX时,就不具体说这些优点了)
  • 类关系
    • 依赖:非常弱的关系,A中用过B即为A依赖B
    • 继承:子类
    • 实现:接口/抽象类
    • 关联(也常看做包含)
      • 聚合:has-a,部分与整体的生命周期可以不同
      • 组合:contains-a,更强,部分依赖整体的生命周期
  • 接口这里单独强调下接口,作为最重要的抽象形式之一,接口可以看做设计模式的基石,所以面向接口编程被广泛采用。接口即契约。好的接口必须小而精(高内聚),但是也需避免接口膨胀和过度设计,这是一个权衡。

目标

  • 优点:使得系统灵活可扩展,也即使用设计模式的目标
  • 缺点:增加系统复杂度、有过度设计的风险因此适用于系统会不断发生变化或者新老系统共存的场景。

原则

  • 隔离变化
  • 开(扩展)闭(修改)
  • 高内聚/低耦合(High Cohesion/Low Coupling)
    • 单一职责(Single Responsibility)
    • 面向接口
  • 接口隔离:小、高内聚
  • 依赖倒置(Dependence Inversion):高层依赖底层、依赖抽象

模式总结

  1. Strategy:使用接口即使用strategy,用于隔离变化,例如Spring中IOC(依赖反转)。
  2. Decrator:常见于各种wrapper,常用于在原函数执行前后做一些额外的工作,例如定制输入/输出流、加解密、AOP等。
  3. Factory Method:隔离创建对象的细节,使得创建对象的行为可扩展,一般配合singleton使用,例如commons的LogFactory。
  4. Observer:非常实用,即订阅/发布模型,用于事件驱动的设计,例如UI框架中的listener。
  5. Chain of Responsibility:一组对象按照既定的顺序关联起来,依次处理请求,其中任一对象都有权停止调用的继续传递,例如JavaEE中的Filter。
  6. Singleton:最简单的模式,但是要注意线程安全的单例模式的几种写法,在延迟加载的场景中:double-check的隐患,以及静态内部类的优点。
  7. Flyweight:复用变化少的对象,常用于各种资源池的设计,例如线程池,再例如在处理音乐对象时,复用音乐家。
  8. Adapter:处理遗留系统的不二法宝,也可以用空方法实现接口作为抽象父类,例如Java AWT中的KeyAdapter、MouseAdapter。
  9. Facade:封装扇出(多个方法的调用简化为一个),复杂的facade可以形成树状结构,本质上是利用树状结构减少调用者的复杂度。
  10. Template:与多态紧密结合,其实任意的多态使用即为该模式,可以理解为框架与钩子(callback之类)的关系,例如Spring MVC。
  11. Builder:与factory不同的是,该模式包含了对象构造的若干过程,因此天然地与template结合,例如StringBuilder、protobuf中的builder等。
  12. Iterator:封装数据的访问行为(顺序、可见性等),一般被容器类创建,例如由Java的Iterable实现类创建。
  13. Composite:结构上与decorator很像,但可以一个包装多个同接口的实例,在逻辑上也不同,composite将组件组装为整体使用,decorator仅仅是修饰目标的行为,例如目录与文件。
  14. Command:将行为抽象和解耦,例如绘图命令包含钢笔、笔刷、油漆桶等,每个命令可以包含draw、undo、redo等操作。
  15. Mediator:对于n个对象,可能共有O(n^2)个联系,使用mediator可以将复杂可变的联系行为封装在该类中,每个对象只需和该类联系即可,例如UI中的组件状态的关联(联动菜单等)。
  16. State:封装FSM(有限状态机)的状态与状态迁移,每个状态定义了自身的输入与状态迁移,比传统的switch写法更灵活,例如电梯调度。
  17. Proxy:与decorator在结构上很像,但逻辑上不同,decorator是在原有的基础上做额外的工作,而proxy是原对象的一个完整的替代品,例如图片加载中的占位符、AOP。
  18. Abstract Factory:该模式抽象出创建一组相关对象的接口,其中每个方法即为factory method,例如创建一组相关的UI控件等。
  19. Prototype:用于以某个对象为模子创建一个新对象的场景,例如幻灯片中的母版与普通页、对象的克隆(Java中的Cloneable)等。
  20. Bridge:使用关联代替继承,解决类多维度的扩展导致的类爆炸的问题,例如一本书,从语言上看分为中文英文等(共X种),从类别上分为小说散文等(共Y种),从包装上分为精装平装等(共Z种),那么如果采用继承需要3层共XYZ个类,如果分别包含三种分类的接口,则一共只需X+Y+Z个类。
  21. Interpreter:很少用到,一般用于解释执行自定义的某种语法,跟command与composite可以合起来使用举个我在实际工作中用过的例子:规则过滤。该模块输入是仿SQL语法的过滤规则,例如:syndId=101 AND sponsor.id IN (1,2,3) AND campaign.id NOT IN (4,5,6)可以将一元、二元之类的表达式封装为command,command之间是composite的模式(可以构造为一棵抽象语法树),command本身其实就是不同的interpreter,接受context(实际应用中我是将context与context的求值逻辑分离开了,便于扩展不同的context求值逻辑)作为参数。
  22. Memento:将当前对象的状态信息保存为另一个对象(状态镜像),使得当前对象可以基于状态镜像快速恢复原状态,例如表单提交后,将已填写正确的字段作为镜像传递给视图层,以便用户继续填写的时候可以只用重写错误的信息。
  23. Visitor:访问多种类型的元素时,很容易写出if-else的代码,如果类型变化不大但是访问的行为(例如输出元素)容易发生变化时,适合此模式。具体地,为每个元素定义访问行为的接口,在对应的实现中可以调用某个visitor,而visitor的实现类定义具体的实现。例如解析HTML DOM树。

转载信息:链接

这篇关于一句话总结GoF 23种设计模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/844333

相关文章

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

Python依赖库的几种离线安装方法总结

《Python依赖库的几种离线安装方法总结》:本文主要介绍如何在Python中使用pip工具进行依赖库的安装和管理,包括如何导出和导入依赖包列表、如何下载和安装单个或多个库包及其依赖,以及如何指定... 目录前言一、如何copy一个python环境二、如何下载一个包及其依赖并安装三、如何导出requirem

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Git提交代码详细流程及问题总结

《Git提交代码详细流程及问题总结》:本文主要介绍Git的三大分区,分别是工作区、暂存区和版本库,并详细描述了提交、推送、拉取代码和合并分支的流程,文中通过代码介绍的非常详解,需要的朋友可以参考下... 目录1.git 三大分区2.Git提交、推送、拉取代码、合并分支详细流程3.问题总结4.git push

Kubernetes常用命令大全近期总结

《Kubernetes常用命令大全近期总结》Kubernetes是用于大规模部署和管理这些容器的开源软件-在希腊语中,这个词还有“舵手”或“飞行员”的意思,使用Kubernetes(有时被称为“... 目录前言Kubernetes 的工作原理为什么要使用 Kubernetes?Kubernetes常用命令总

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO