Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

编程中的23种设计模式 #59

Open
giscafer opened this issue Oct 11, 2022 · 0 comments
Open

编程中的23种设计模式 #59

giscafer opened this issue Oct 11, 2022 · 0 comments

Comments

@giscafer
Copy link
Owner

王争《设计模式之美》专栏学习笔记

设计模式要干的事情就是解耦。创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦。

设计模式在于设计的意图,也就是应用场景。如果单纯看设计思路或者代码实现,一些模式是比较相似的,比如策略模式和工厂模式。

借助设计模式,我们利用更好的代码结构,将一大坨代码拆分成职责更单一的小类,让其满足开闭原则,高内聚低耦合等特性,从此来控制和应对代码的复杂性,提供代码的可扩展性。

创建型模式

解决对象的创建问题

  • 单例模式
  • 工厂模式
  • 建造者模式
  • 原型模式

结构性模式

类或对象的组合或组装

  • 代理模式
    • 增强原始类无关的功能
    • 常用于:监控、统计、鉴权、限流、事务、幂等、日志、RPC、缓存等
  • 桥接模式
    • “抽象”和“实现”独立开发,通过对象之间的组合关系,组装在一起。
    • 应用1:JDBC驱动(JDBC和Driver独立开发,组合在一起)
    • 应用2:API监控告警,通知渠道:邮件、短信、微信、自动语音电话;紧急程度:严重、紧急、普通、无关要紧;不同的紧急程度对应不同的通知渠道
  • 装饰器模式
    • 增强原始类相关的方法(所以需要继承同样的父类或者实现同样的接口),能嵌套多个装饰器
    • 应用1:Java IO 流
    • 应用2:增加缓存
  • 适配器模式
    • “补救策略”,提供跟原始类不同的接口。代理模式和装饰器模式提供的都是跟原始类相同的接口。
    • 应用:
      • 封装有缺陷的接口设计
      • 统一多个类的接口设计
      • 替换依赖的外部系统
      • 兼容老版本接口
      • 适配不同的数据格式
  • 门面模式
    • 解决的是接口易用性、性能、事务问题,而适配器解决的是原接口和目标接口不适配的兼容性问题。
    • 应用:子系统(或App)需要调用多个接口的情况;用户和钱包两个领域的分布式事务问题。
  • 组合模式
    • 应用:文件系统目录结构
  • 享元模式
    • 目的是共享使用对象,达到复用目的(通过一个List或Map缓存已经创建好的享元对象)
    • 应用1:棋牌模式、文本编辑器
    • 应用2:Java Integer(-127~127利用享元模式提前创建好)、String 利用享元模式复用字符串常量。

行为型模式

类或对象之间的交互

  • 观察者模式
    • 也称为发布订阅模式,是一对多的关系。将观察者和被观察者代码解耦。
    • 应用1:RSS Feeds,邮件订阅
    • 应用2:进程内有同步阻塞或异步非阻塞实现方式,异步非阻塞如EventBus;跨进程的观察者模式如RPC接口调用,消息队列MQ
    • 生产者>消费者的区别:
      • 生产者和消费者是以异步实现,多对多,并且消费者存在竞争关系,一条消息只能被一个消费者消费。
      • 发布订阅则可以同步也可以异步方式实现,一对多,一条消息可以被多个订阅者消费,订阅者没有竞争关系,发布和订阅两者也在流程上存在先后关系
  • 模板模式
    • 模板方法和回调应用场景是一致的,都是定义好算法骨架,并对外开放扩展点,符合开闭原则;两者的却别是代码的实现上不同,模板方法是通过继承来实现,是自己调用自己回调是类之间的组合。
    • 应用:JdbcTemplate、RedisTemplate、RestTemplate
  • 策略模式
    • 解耦策略的定义、创建、使用,控制代码复杂度,让每个部分都不至于过复杂,代码行数过多。移除 if-else 和 switch-case 分支逻辑判断(策略工厂),保证代码的可维护性,和遵循KISS原则。
    • 应用:对一个文件进行排序。文件中只有整数,并且相邻的数字通过逗号区隔。文件的大小可能:10GB(外部排序)、100GB(多线程外部排序)、 1TB(多机MapReduce)。
  • 职责链模式
    • 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
    • 应用:敏感词过滤、Servlet Filter、Spring Interceptor
  • 状态模式
    • 又叫有限状态机,有3个部分组成:状态、事件、动作。其中,事件也称为转移条件。事件触发转态的转移和动作的执行。动作可以不是必须的。状态机的三种实现方式:分支逻辑法、查表法、状态模式。
    • 应用:游戏、工作流引擎
  • 迭代器模式
    • 数组遍历器,在编程语言中已经提供为一种类库来使用
    • 应用:1、遍历集合的同时不要增删元素;2、设计一个支持快照功能的iterator
  • 访问者模式
    • 允许一个或多个操作应用到一组对象上,解耦操作和对象本身。双分派语言(Double Dispatch)不需要支持访问者模式
    • 应用:批量处理PDF、PPT、Word文件,提取内容放到 txt 文件中。定义访问者类(Extractor、Compressor),将对象和操作解耦,将业务操作抽离出来,使得符合开闭原则。
  • 备忘录模式
    • 也叫快照模式,在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,一遍之后方便恢复对象为先前状态。
    • 应用:防丢失、撤销、恢复等。通过全量备份和增量备份结合的方式(低频全量备份,高频增量备份),减少存储和时间的消耗。
  • 命令模式
    • 命令模式将请求(命令)封装为一个对象,这样可以使用不同的请求参数化其他对象(将不同请求依赖注入到其他对象),并且能够支持请求(命令)的排队执行、记录日志、撤销等(附加控制)功能。
    • 应用:用来控制命令的执行,比如:异步、延迟、排队执行命令、存储命令、给命令记录日志等。
  • 解释器模式
    • 解释器模式为某个语言定义它的语法(或者叫文法)表示,并定义一个解释器来处理这个语法。
    • 应用:1、告警规则,如触发条件:key1 > 100 && key2 < 1000 || key3 == 200;2、计算表达式等,如 8 3 2 4 - + *
  • 中介模式
    • 中介模式的设计思想跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系(或者依赖关系)从多对多(网状关系)转换为一对多(星状关系)。原来一个对象要跟 n 个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低了代码的复杂度,提高了代码的可读性和可维护性。
    • 应用:UI交互,如注册用户页面,切换用户登录和用户注册的UI,显示不同输入框等。
    • 与观察者模式的区别:中介模式一般可以控制参与者的执行顺序,而观察者一般控制不了。

总结

熟悉23种设计模式的原理、实现、设计意图和应用场景。避免过度设计,避免设计不足。设计的初衷是提高代码质量,不要脱离具体的场景去谈设计。

设计模式

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant