引子:无论在平时开发过程中,还是深夜研读源码亦或者面试时都对遇到——设计模式。比如说Spring中的单例模式(bean单例)、工厂模式(bean创建)、代理模式(动态代理)、策略模式等。我们将设计模式分为创建型、结构型、行为性三大类。本篇文章带你一次搞定23种设计模式。
首先来看一道面试题,热热身:
Q&A:你知道Spring中运用了哪些设计模式吗?
无非是考察设计模式的应用,以下所有设计模式在源码中应用,请查收。
- 工厂方法模式:AbstractBeanFactory 。
- 抽象工厂模式:在 Spring 中,BeanFactory。
- 单例模式:Spring中创建单例。
- 建造者模式:解析xml文件。
- 原型模式:在创建ioc容器后,通过getBean()获取bean对象时,往里追可以发现在核心方法处spring对bean的scope属性进行了判断,配置了prototype时。
- 适配器模式:spring AOP中的MethodBeforeAdviceAdapter类。
- 装饰模式:TransactionAwareCacheDecorator 类。
- 代理模式:spring中代理有两种,Jdk代理方式和CGLIB。
- 外观模式:Tomcat 中,catalina.jar 中的 RequestFacade 和 ResponseFacade 。
- 桥接模式:JDBC。
- 组合模式:CompositeCacheManager,Mybatis 在处理 xml 动态 sql 中用到了。
- 享元模式:String常量池, Integer 的静态内部类 IntegerCache。
- 策略模式:Cglib2AopProxy和JdkDynamicAopProxy分别代表两种策略的实现方式。
- 模板方法模式:JdbcTemplate实现了一系列常用的数据访问的算法骨架。
- 观察者模式: ApplicationListener, ContextLoaderListener等。
- 迭代器模式:集合。
- 责任链模式:handler,filter,Intercept。
- 命令模式:Tomcat 中命令模式在 Connector 和 Container 组件之间有体现。
- 备忘录模式:spring-webflow 中的stateManageableMessageContext.createMessageMemento() 状态模式:spring-statemachine spring状态机。
- 访问者模式:Spring 中的 BeanDefinitionVisitor 类主要用于访问 BeanDefinition。
- 中介者模式:Java web 开发中 MVC 模式(Model-View-Controller)就用到了中介者模式,Controller 就是 Model 和 View 的中介。
- 解释器模式:在 Spring 中,ExpressionParser 接口内部采用的是解释器模式。
Q&A:什么是设计模式?
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当⻓的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
Q&A:软件设计原则有哪些?
- 开闭原则(Open Closed Principle,OCP)
- 单一职责原则(Single Responsibility Principle, SRP)
- 里氏替换原则(Liskov Substitution Principle,LSP)
- 依赖倒置原则(Dependency Inversion Principle,DIP)
- 接口隔离原则(Interface Segregation Principle,ISP)
- 合成/聚合复用原则(Composite/Aggregate Reuse Principle,C/ARP)
- 最少知识原则(Least Knowledge Principle,LKP)或者迪米特法则(Law of Demeter,LOD)
一、设计模式分类(5 + 7 + 11)
- 创建型模式(5种):单例模式、工厂模式、抽象工厂模式、原型模式、建造者模式
- 结构型模式(7种):适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式
- 行为型模式(11种):模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式
二、23 种设计模式定义
- 单例模式(Single Pattern):某个类只能存在一个对象实例
- 工厂模式(Factory Pattern):由工厂对象决定创建出哪种产品类的实例
- 原型模式(Prototype Pattern):用原型实例指定创建对象种类,并通过拷贝原型创建新的对象
- 建造者模式 / 生成器模式(Builder Pattern):将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象
- 适配器模式(Adapter Pattern):将某个类的接口转换成客户端期望的另一个接口表示
- 桥接模式(Bridge Pattern):将实现与抽象分离,放在两个不同的类层次中,可以独立改变
- 装饰者模式(Decorator Pattern):动态地将新功能附加到对象上
- 组合模式 / 部分整体模式(Composite Pattern):依据树形结构来组合对象,用来表示部分以及整体层次
- 外观模式 / 过程模式(Facade Pattern):为调用端提供统一的调用接口
- 享元模式 / 蝇量模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象
- 代理模式(Proxy Pattern):通过代理对象访问目标对象
- 模板模式 / 模板方法模式(Template Method Pattern):定义一个操作中的算法骨架,将一些步骤延迟到子类中
- 命令模式(Command Pattern):将发起请求的对象与执行请求的对象解耦
- 访问者模式(Visitor Pattern):将数据结构与数据操作分离
- 迭代器模式(Iterator Pattern):提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素
- 观察者模式(Observer Pattern):对象之间多对一依赖的一种设计方案
- 中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互
- 备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态
- 解释器模式(Interpreter Pattern):给定一个语言并定义其文法表示,使用该解释器来解释语言中的句子
- 状态模式(State Pattern):解决对象在多种状态转换时,需要对外输出不同的行为的问题
- 策略模式(Strategy Pattern):定义算法族,分别封装起来,让他们之间可以互相替换
- 职责链模式 / 责任链模式(Chain of Responsibility Pattern):为请求创建一个接收者对象的链
三、23种设计模式举例、源码及优缺点
分类 | 设计模式 | 举例 | 源码 | 优点 | 缺点 |
---|---|---|---|---|---|
创建型 | 单例模式 | Singleton | JDK 中java.lang.Runtime | 节省资源,提高性能 | |
~ | 工厂模式 | 披萨店 | JDK 中Calendar | 统一管理,便于维护 | |
~ | 原型模式 | 克隆羊 | Spring 中ApplicationContext | 简化过程,提高效率 | 复杂;违背 OCP |
~ | 建造者模式 | 盖房子 | JDK 中StringBuilder | 解耦创建过程 | |
结构型 | 适配器模式 | 插座 | SpringMVC 中HandlerAdapter | 兼容性 | |
~ | 桥接模式 | 手机 | JDBC 中Driver | 分离抽象与实现 | |
~ | 装饰者模式 | 星巴克咖啡 | JDK 中FilterlnputStream | 动态扩展功能 | |
~ | 组合模式 | 学校院系 | JDK 中HashMap | 明确部分与整体层次 | |
~ | 外观模式 | 影院管理 | MyBatis 中Configuration | 屏蔽细节,简化操作 | 过多不利于维护 |
~ | 享元模式 | 网站展示 | JDK 中Integer | 降低内存,提高效率 | 复杂 |
~ | 代理模式 | 教师教书 | JDK 中Proxy | 扩展功能,更加安全 | |
行为型 | 模板模式 | 豆浆制作 | Spring 中AbstractApplicationContext | 统一算法,代码复用 | 过多不利于维护 |
~ | 命令模式 | 智能生活 | Spring 中JdbcTemplate | 解耦请求发起与执行 | 复杂 |
~ | 访问者模式 | 测评系统 | 解耦数据结构与操作 | 违背迪米特、依赖倒转 | |
~ | 迭代器模式 | 学校院系 | JDK 中ArrayList | 统一遍历 | 过多不利于维护 |
~ | 观察者模式 | 天气预报 | JDK 中Observable | 动态添加三方 | |
~ | 中介者模式 | 智能家庭 | 封装交互 | 复杂 | |
~ | 备忘录模式 | 游戏角色状态恢复 | 方便恢复状态 | 占用资源,消耗内存 | |
~ | 解释器模式 | 四则运算 | Spring 中SpelExpressionParser | 可扩展性 | 调试复杂;效率低 |
~ | 状态模式 | APP 抽奖 | 借贷平台 | 分离状态 | 过多不利于维护 |
~ | 策略模式 | 鸭子 | JDK 中Comparator | 分离不变与变化 | 过多不利于维护 |
~ | 职责链模式 | 采购审批 | SpringMVC 中HandlerExecutionChain | 分离请求与处理 | 调试复杂;影响性能 |
参考网址:https://ai.com/
https://blog.youkuaiyun.com/qq_35925558/category_11416999.html