设计模式之各种设计模式总结与对比
目录
- 1 目标
- 2 定位
- 3 一句话归纳设计原则
- 4 G0F 23种设计模式简介
- 5 设计模式使用频次总结
- 6 —句话归纳设计模式
- 7 设计模式之间的关联关系和对比
1 目标
1、 简要分析GoF 23种设计模式和设计原则,做整体认知。
2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。
3、 了解各设计模式之间的关联,解决设计模式混淆的问题。
2 定位
1、 掌握设计模式的"道" ,而不只是"术"
2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。
3、 不要为了用设计模式去生搬硬套,而是在业务上到遇到问题时,很自然地想到设计模式作为一种解 决方案。
3 一句话归纳设计原则
| 设计原则 | 一句话归纳 | 目的 |
|---|---|---|
| 开闭原则(OCP)(Open-Close) | 对扩展开放,对修改关闭 | 减少维护带来新的风险 |
| 依赖倒置原则(DIP)(Dependence Inversion) | 高层不应该依赖低层 | 更利于代码结构的升级扩展 |
| 单一职责原则(SRP)(Simple Responsibility) | 一个类只干一件事 | 便于理解,提高代码可读性 |
| 接口隔离原则(ISP)(Interface Segregation) | 一个接口只干一件事 | 功能解耦,高聚合、低耦合 |
| 迪米特法则(LoD)(Law of Demeter) | 不该知道的不要知道 | 只和朋友交流,不和陌生人说话,减少代码臃肿 |
| 里氏替换原则(LSP) (Liskov Substitution) | 子类重写方法功能发生改变, 不应该影响父类方法的含义 | 防止继承泛滥 |
| 合成复用原则(CARP)(Composite/Aggregate Reuse) | 尽量使用组合实现代码复用,而不使用继承 | 降低代码耦合 |
4 G0F 23种设计模式简介
《Design Patterns: Elements of Reusable Object-Oriented Software》 (即 后 述 《设计模式》 — 书 ) ,由 Erich Gamma、 Richard Helm、 Ralph Johnson 和 John Vlissides 合著 (Addison-Wesley , 1995 )。这几位作者常被称为"四人组(Gang of Four)" ,而这本书也就被称为 "四人组(或 GoF )"书。
在 《设计模式》这本书的最大部分是一个目录,该目录列举并描述了 23种设计模式。另外,近来 这一清单又增加了一些类别,最重要的是使涵盖范围扩展到更具体的问题类型。例如,Mark Grand在 Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML (即后述《模式 Java 版》一书)中增加了解决涉及诸如并发等问题的模式,而 由 DeepakAlur. JohnCrupi和 Dan Malks 合著的 Core J2EE Patterns: Best Practices and Design Strategies —书中主要关注使用 Java 2 企 业技术的多层应用程序上的模式。
很多人并没有注意到这点,学完Java基础语言就直接去学J2EE,有的甚至鸭子赶架,直接使用起 Weblogic等具体J2EE软件,一段时间下来,发现不过如此,挺简单好用,但是你真正理解J2EE 了吗? 你在具体案例中的应用是否也是在延伸J2EE的思想?对软件设计模式的研究造就了一本可能是面向对 象设计方面最有影响的书籍:《设计模式》。
由此可见,设计模式和J2EE在思想和动机上是一脉相承的,我总结了以下几个原因:
- 设计模式更抽象,J2EE是具体的产品代码,我们可以接触到,而设计模式在对每个应用时才会产 生具体代码。
- 设计模式是比J2EE等框架软件更小的体系结构,J2EE中许多具体程序都是应用设计模式来完成的 ,当你深入到J2EE的内部代码研究时,这点尤其明显,因此,如果你不具备设计模式的基础知识(GoF 的设计模式),你很淮i夬速的理解J2EE。不能理解J2EE如何能灵活应用?
- J2EE只是适合企业计算应用的框架软件,但是GoF的设计模式几乎可以用于任何应用!因此GoF 的设计模式应该是J2EE的重要理论基础之一
所以说,GoF的设计模式是Java基础知识和J2EE框架知识之间一座隐性的”桥“。
设计模式其实也是一门艺术。设计模式来源于生活,不要为了套用设计模式而去使用设计模式。设 计模式是在我们迷茫时提供的一种解决问题的方案,或者说用好设计模式可以防范于未然。自古以来, 在我们人生迷茫时,我们往往都会寻求帮助,或上门咨询,或查经问典。就在几千年前,孔夫子就教给 了我们怎样做人。对于中国人来说都知道:从出生元婴、二十加冕、三十而立、四十不惑、五十知天命、 六十花甲、七十古稀不逾矩、八、九十耄耋…我们这就是在用模板模式,当然,有些人不会选择这套 模板。
设计模式总结的是经验之谈总结的是前人的经验,提供给后人去借鉴使用,前人栽树,后人乘凉。 设计模式可以帮助我们提升代码的可读性、可扩展性;降低维护成本;解决复杂的业务问题,但是,千 万千万不要死记硬背,生搬硬套。下面我们还是先来总体预览一下GOF23种设计模式的归纳和总结。
| 分类 | 设计模式 |
|---|---|
| 创建型 | 工厂方法模式(Factory Method )、抽象工厂模式(Abstract Factory ) 、单例模式(Singleton)、原型模式(Prototype、 建造者模式(Builder) |
| 结构型 | 代理模式(Proxy ) 、门面模式( Facade ) 、装饰器模式(Decorator) 、孚兀模式( Flyweight) 、组合模式(Composite)、适配器模式(Adapter)、桥接模式(Bridge ) |
| 行为型 | 模板方法模式(Template Method ) 、策略模式(Strategy ) 、 责任链模式(Chain of Responsibility ) 、迭代器模式(Iterator) 、命令模式(Command ) 、 状态模式(State ) 、备忘录模式(Memento ) 、中介者模式(Mediator) 、 解释器模式(Interpreter)、观察者模式(Observer) 、访问者模式(Visitor) |
5 设计模式使用频次总结
创建型模式(Creational)
高频: 工厂方法模式(Factory Method ) 、抽象工厂模式(Abstract Factory ) 、单例模式(Singleton)、建 造者模式(Builder)
低频 : 原型模式( Prototype )
结构型模式(Structural)
高频: 代理模式(Proxy ) 、门面模式(Facade ) 、装饰器模式(Decorator) 、享元模式(Flyweight) 、适配器模式(Adapter)、组合模式(Composite )
低频 : 桥接模式( Bridge )
行为型模式(Behavioral)
高频: 模板方法模式(Template Method ) 、策略模式(Strategy ) 、 责任链模式(Chain of Responsibility ) 、状态模式(State )
低频: 备忘录模式(Memento ) 、 观察者模式(Observer) s 迭代器模式(Iterator) s 中介者模式(Mediator)、命令模式(Command ) 、解释器模式( Interpreter) 、访问者模式(Visitor)
6 —句话归纳设计模式
各设计模式对比及编程思想总结
| 设计模式 | 一句话归纳 | 目的 | 生活案例 | 框架源码举例 |
|---|---|---|---|---|
| 工厂模式(Factory ) | 产品标准化,生产更局效 | 封装创建细节 | 实体工厂 | LoggerFactory、 Calender |
| 单例模式(Singleton ) | 世上只有一个Tom | 保证独一无二 | CEO | BeanFactory、 Runtime |
| 原型模式(Prototype ) | 拔一根猴毛,吹出干万个 | 高效创建对象 | 克隆 | ArrayList、PrototypeBean |
| 建造者模式(Builder) | 高配中配与低配, 想选哪配就哪配 | 开放个性配置步骤 | 选配 | StringBuilder、BeanDefinitionBuilder |
| 代理模式(Proxy ) | 没有资源没时间, 得找媒婆来帮忙 | 增强职责 | 媒婆 | ProxyFactoryBean、JdkDynamicAopProxy、CglibAopProxy |
| 门面模式(Facade) | 打开一扇门,走向全世界 | 统一访问入口 | 前台 | JdbcUtils、RequestFacade |
| 装饰器模式(Decorator) | 他大舅他二舅,都是他舅 | 灵活扩展、同宗同源 | 煎饼 | BufferedReader、Inputstream |
| 享元模式(Flyweight) | 优化资源配置,减少重复浪费 | 共享资源池 | 全国社保联网 | String、Integer、ObjectPool |
| 组合模式(Composite) | 人在一起叫团伙, 心在一起叫团队 | 统一整体和个体 | 组织架构树 | HashMap、SqINode |
| 适配器模式(Adapter) | 适合自己的,才是最好的 | 兼容转换 | 电源造配 | AdvisorAdapten、HandlerAdapter |
| 桥接模式(Bridge) | 约定优于配置 | 不允许用继承 | 桥 | DriverManager |
| 委派模式(Delegate ) | 这个需求很简单, 怎么实现我不管 | 只对结果负责 | 授权委托书 | ClassLoader、 BeanDefinitionParserDelegate |
| 模板模式(Template ) | 流程全部标准化, 需要微调请覆盖 | 逻辑复用 | 把大象装进冰箱 | JdbcTemplate、HttpServlet |
| 策略模式(Strategy) | 条条大道通北京, 具体哪条你来定 | 把选择权交给用户 | 选择支付方式 | Comparator、 Instantiationstrategy |
| 责任链模式(Chain of Responsibility) | 各人自扫门前雪,莫管他人瓦上霜 | 解耦处理逻辑 | 踢皮球 | FilterChain、Pipeline |
| 迭代器模式(Iterator) | 流水线上坐一天,每个包裹扫 | 统一对集合的访问 | 逐个检票进站 | Iterator |
| 命令模式(Command) | 运筹帷幄之中, 决胜干里之外 | 解耦请求和处理 | 遥控器 | Runnable、TestCase |
| 状态模式(State) | 状态驱动行为, 行为决定状态 | 绑定状态和行为 | 订单状态跟踪 | Lifecycle |
| 备忘录(Memento) | 给我一剂"后悔药“ | 备份 | 草槁箱 | StateManageableMessageContext |
| 中介者(Mediator) | 联系方式我给你, 怎么搞定我不管 | 统一管理网状资源 | 朋友圈 | Timer |
| 解释器模式(Interpreter) | 我 想 说 "方 言 ", 一切解释权归我所有 | 实现特定语法解析 | 摩斯密码 | Pattern、ExpressionParser |
| 观察者模式(Observer) | 到点就通知我 | 解耦观察者与被观察者 | 闹钟 | ContextLoaderListener |
| 访问者模式(Visitor) | 横看成岭侧成峰, 远近高低各不同 | 解耦数据结构和数据操作 | KPI考核 | FileVisitor、BeanDefinitionVisitor |
7 设计模式之间的关联关系和对比
单例模式和工厂模式
实际业务代码中,通常会把工厂类设计为单例。
策略模式和工厂模式
1、工厂模式包含工厂方法模式和抽象工厂模式是创建型模式,策略模式属于行为型模式。
2、工厂模式主要目的是封装好创建逻辑,策略模式接收工厂创建好的对象,从而实现不同的行为。
策略模式和委派模式
1、策略模式是委派模式内部的一种实现形式,策略模式关注的结果是否能相互替代。
2、委派模式更关注分发和调度的过程。
模板方法模式和工厂方法模式
工厂方法是模板方法的一种特殊实现。

对于工厂方法模式的create。方法而言,相当于只有一个步骤的模板方法模式。这一个步骤交给子类去 实现。而 模 板 方 法 呢 ,将 needHomework方 法 和 checkHomework方法交给子类实现, needHomework方法和checkHomework方法又属于父类的某一个步骤且不可变更。
模板方法模式和策略模式
1、 模板方法和策略模式都有封装算法。
2、 策略模式是使不同算法可以相互替换,且不影响客户端应用层的使用。
3、 模板方法是针对定义一个算法的流程,将一些有细微差异的部分交给子类实现。
4、模板方法模式不能改变算法流程,策略模式可以改变算法流程且可替换。策略模式通常用来代替 if…else…等条件分支语句。

1、WechatPay、JDPay、AliPay是交给用户选择且相互替代解决方案。而 JdbcTemplate下面的子类是不能相互代替的。
2、策略模式中的queryBalanceOTJ法虽然在pay。方法中也有调用,但是这个逻辑只是出于程序健壮 性考虑。用户完全可以自主调用que「yBalance()方法。而模板方法模式中的mapRow()方法一定要在 获 得 ResultSet之后方可调用,否则没有意义。
装饰者模式和静态代理模式
1、 装饰者模式关注点在于给对象动态添加方法,而代理更加注重控制对对象的访问。
2、 代理模式通常会在代理类中创建被代理对象的实例,而装饰者模式通常把被装饰者作为构造参数。

装饰者和代理者虽然都持有对方引用,但逻辑处理重心是不一样的。
装饰者模式和适配史器模式
1、 装饰者模式和适配器模式都是属于包装器模式(Wrapper Pattern ) 。
2、 装饰者模式可以实现被装饰者与相同的接口或者继承被装饰者作为它的子类,而适配器和被适配者 可以实现不同的接口。

装饰者和适配器都是对SiginService的包装和扩展,属于装饰器模式的实现形式。但是装饰者需要满足 OOP的 is-a关系,我们也讲过煎饼的例子,不管如何包装都有共同的父类。而适配器主要解决兼容问 题 ,不一定要统一父类,上图中LoginAdapter和 RegistAdapter就是兼容不同功能的两个类’但 RegistForQQAdapter需要注册后自动登录,因此既继承了 RegistAdpter又继承了 LoginAdapter。
适配器模式和静态代理模式
适配器可以结合静态代理来实现,保存被适配对象的引用,但不是唯一的实现方式。
适配器模式和策略模式
在适配业务复杂的情况下,利用策略模式优化动态适配逻辑。
相关文章:
设计模式之各种设计模式总结与对比
目录1 目标2 定位3 一句话归纳设计原则4 G0F 23种设计模式简介5 设计模式使用频次总结6 —句话归纳设计模式7 设计模式之间的关联关系和对比1 目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring…...
JAVA练习55- Fizz Buzz
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-Fizz Buzz 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 2月19日练习…...
LeetCode笔记:Biweekly Contest 98
LeetCode笔记:Biweekly Contest 98 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 比赛链接:https://leetcode.com/contest/biweekly-contest-98 1. 题目一 给出题目一的试题链接如…...
HNUCM-《算法分析与设计》期末考试考前复习题
问题 A: X星人的地盘题目描述一天,X星人和Y星人在一张矩形地图上玩抢地盘的游戏。X星人每抢到一块地,在地图对应的位置标记一个“X”;Y星人每抢到一块地,在地图对应的位置标记一个“Y”;如果某一块地无法确定其归属则标…...
算法导论【分治思想】—大数乘法、矩阵相乘、残缺棋盘
这里写自定义目录标题分治法概述特点大数相乘问题分治算法矩阵相乘分治算法残缺棋盘分治算法分治法概述 在分而治之的方法中,一个问题被划分为较小的问题,然后较小的问题被独立地解决,最后较小问题的解决方案被组合成一个大问题的解决。 通常…...
Java【七大排序】算法详细图解,一篇文章吃透
文章目录一、排序相关概念二、七大排序1,直接插入排序2,希尔排序3,选择排序4,堆排序5,冒泡排序5.1冒泡排序的优化6,快速排序6.1 快速排序的优化7,归并排序三、排序算法总体分析对比总结提示&…...
Autosar OS IOC
Inter-OS-Application Communicator 背景和基本原理General purposeIOC functionalityCommunicationNotificationIOC interface背景和基本原理 The IOC implementation shall be part of the Operating System IOC和操作系统紧密相关,是操作系统实现的一部分 The IO…...
记录一次Binder内存相关的问题导致APP被杀的BUG排查过程
事情的起因的QA压测过程发生进程号变更,怀疑APP被杀掉过,于是开始看日志 APP的压测平台会上报进程号变更时间点,发现是在临晨12:20分,先大概确定在哪个日志文件去找关键信息一开始怀疑是crash,然后就在日志…...
设计模式(十)----结构型模式之适配器模式
1、概述 如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插座转换器,转换器第1面插入当地的插座,第2面…...
【数据结构】——队列
文章目录前言一.什么是队列,队列的特点二、队列相关操作队列的相关操作声明队列的创建1.队列的初始化2.对队列进行销毁3.判断队列是否为空队列4.入队操作5.出队操作6.取出队头数据7. 取出队尾数据8.计算队伍的人数总结前言 本文章讲述的是数据结构的特殊线性表——…...
Android OTA升级常见问题的解决方法
1.1 多服务器编译 OTA 报错 Android7 以后引入了 jack-server 功能,也导致在公共服务器上 编译 Android7 以上的版本时,会出现 j ack-server 报错问题。 在多用户服务器上 编译 dist 时 会出现编译过程中 会将 port_service 和 port_admin 改为 默认的 …...
说说Hibernate
当你在实战项目中需要用到SSH时, 如果你之前只用过Mybatis那自然是不能解决问题的, 因为在很多银行类金融类项目中你可能会使用到Hibernate, 那么关于Hibernate你应该要了解什么呢, 本篇文章就以学习Hibernate框架为目的, 巩固在工作中可能需要用到的这种ORM技术, 同时也欢迎家…...
目标检测论文阅读:DETR算法笔记
标题:End-to-End Object Detection with Transformers 会议:ECCV2020 论文地址:https://link.springer.com/10.1007/978-3-030-58452-8_13 官方代码:https://github.com/facebookresearch/detr 作者单位:巴黎第九大学、…...
Golang sync.Once 源码浅析
本文分析了Golang sync.Once 源码,并由此引申,简单讨论了单例模式的实现、 atomic 包的作用和 Java volatile 的使用。 sync.Once 使用例子 sync.Once 用于保证一个函数只被调用一次。它可以用于实现单例模式。 有如下类型: type instanc…...
C++面向对象(上)
文章目录前言1.面向过程和面向对象初步认识2.引入类的概念1.概念与用法2.类的访问限定符及封装3.类的作用域和实例化4.类的大小计算5.this指针3.总结前言 本文将对C面向对象进行初步介绍,引入类和对象的概念。围绕类和对象介绍一些基础知识,为以后深入学…...
经常用但是不知道什么是BFC?
BFC学习 block formatting context 块级格式上下文 简单理解: 一个独立容器,内部布局不会受到外面的影响 形成条件: 1.浮动元素:float除none之外的值 2.绝对定位:position:absolute,fixed 3.display:inline-blo…...
GO的临时对象池sync.Pool
GO的临时对象池sync.Pool 文章目录GO的临时对象池sync.Pool一、临时对象池:sync.Pool1.1 临时对象的特点1.2 临时对象池的用途1.3 sync.Pool 的用法二、临时对象池中的值会被及时清理掉2.1 池清理函数2.2 池汇总列表2.3 临时对象池存储值所用的数据结构2.4 临时对象…...
高精度算法一
目录 1. 基础知识 2. 大整数 大整数 3. 大整数 - 大整数 1. 基础知识 利用计算机进行数值计算,有时会遇到这样的问题:有些计算要求精度高,希望计算的数的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,…...
2023年全国最新食品安全管理员精选真题及答案1
百分百题库提供食品安全管理员考试试题、食品安全员考试预测题、食品安全管理员考试真题、食品安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 11.预包装食品的标签内容应使用规范的汉字,但可以同时使用&a…...
C++入门:引用
目录 一. 什么是引用 1.1 引用的概念 1.2 引用的定义 二. 引用的性质和用途 2.1 引用的三大主要性质 2.2 引用的主要应用 三. 引用的效率测试 3.1 传值调用和传引用调用的效率对比 3.2 值返回和引用返回的效率对比 四. 常引用 4.1 权限放大和权限缩小问题 4.2 跨…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
