Loading

设计模式笔记

GOF

在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。

设计模式核心

  • 对接口编程而不是对实现编程。

  • 优先使用对象组合而不是继承。

设计模式总览

创建型模式(Creational Patterns)

  • 单例(Singleton)模式: 保证一个对象

  • 原型(Prototype)模式: 快速克隆一个自己

  • 工厂方法(FactoryMethod)模式:

    • 简单工厂(一个方法): if-else判断创造对象。产品线单一

    • 工厂方法(很多方法): 每个产品一个方法就行。

  • 抽象工厂(AbstractFactory)模式

    • 很多工厂+很多方法;
  • 建造者(Builder)模式: 每一个建造细节都可以传入,但是都不是必须
    如果是必须,就构造器强制

结构型模式(Structural Patterns)

  • 适配器(Adapter)模式

  • 桥接(Bridge)模式

  • 装饰(Decorator)模式

  • 外观(Facade)模式

  • 享元(Flyweight)模式

  • 组合(Composite)模式

  • 过滤器(Filter Pattern)模式

行为型模式(Behavioral Patterns)

  • 模板方法(Template Method)模式

  • 策略(Strategy)模式

  • 命令(Command)模式

  • 职责链(Chain of Responsibility)模式

  • 状态(State)模式

  • 观察者(Observer)模式

  • 中介者(Mediator)模式

  • 迭代器(Iterator)模式

  • 访问者(Visitor)模式

  • 备忘录(Memento)模式

  • 解释器(Interpreter)模式

组件的生命周期

面向对象设计七大原则

开闭原则(Open Closed Principle,OCP)

  • 软件实体应当对扩展开放,对修改关闭

  • 合成复用原则、里氏替换原则相辅相成,都是开闭原则的具体实现规范

  • 扩展新类而不是修改旧类

里氏替换原则(Liskov Substitution Principle,LSP)

  • 继承必须确保超类所拥有的性质在子类中仍然成立

  • 继承父类而不去改变父类

依赖倒置原则(Dependence Inversion Principle,DIP)

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象

  • 例如Controller 注入接口Service而不是接口实现类ServiceImpl

  • 面向接口编程,而不是面向实现类

单一职责原则(Single Responsibility Principle,SRP)

  • 一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分

  • 每个类只负责自己的事情,而不是变成万能

接口隔离原则(Interface Segregation Principle,ISP)

  • 一个类对另一个类的依赖应该建立在最小的接口上

  • 各个类建立自己的专用接口,而不是建立万能接口

迪米特法则(Law of Demeter,LoD)

  • 最少知识原则(Least Knowledge Principle,LKP)

  • 只与你的直接朋友交谈,不跟“陌生人”说话

  • 无需直接交互的两个类,如果需要交互,使用中间者

  • 过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低

合成复用原则(Composite Reuse Principle,CRP)

  • 又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)

  • 软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

  • 优先组合,其次继承

创建型模式(Creational Patterns)

为什么要用创建型模式

  • 创建型模式关注点“怎样创建出对象?”

  • 将对象的创建与使用分离。

  • 降低系统的耦合度

  • 使用者无需关注对象的创建细节

  • 对象的创建由相关的工厂来完成;(各种工厂模式)

  • 对象的创建由一个建造者来完成;(建造者模式)

  • 对象的创建由原来对象克隆完成;(原型模式)

  • 对象始终在系统中只有一个实例;(单例模式)

单例(Singleton)模式

  • 一个单一的类,负责创建自己的对象,同时确保系统中只有单个对象被创建。

  • 某个类只能有一个实例;(构造器私有)

  • 它必须自行创建这个实例;(自己编写实例化逻辑)

  • 它必须自行向整个系统提供这个实例;(对外提供实例化方法)

实现方法

  • 双重检查锁
public class SafeDoubleCheckedLocking {
    private volatile static Instance instance;

    public static Instance getInstance() {
        if (instance == null) {
            synchronized (SafeDoubleCheckedLocking.class) {
                if (instance == null)
                    instance = new Instance();//instance 为 volatile,现在没问题了 
            }
        }
        return instance;
    }
}
  • 基于类初始化
public class InstanceFactory {
    private static class InstanceHolder {
        public static Instance instance = new Instance();
    }

    public static Instance getInstance() {
        return InstanceHolder.instance ;  // 这里将导致 InstanceHolder 类被初始化 
    }
}
  • 基于枚举
public enum Singleton {

    INSTANCE;

    public void doSomething() {
        System.out.println("doSomething");
    }

}

使用场景

  • 多线程中的线程池

  • 数据库的连接池

  • 系统环境信息

  • 上下文(ServletContext)

原型(Prototype)模式

  • 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能

  • 本体给外部提供一个克隆体进行使用

使用场景

  • 资源优化

  • 性能和安全要求

  • 一个对象多个修改者的场景。

  • 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时可以考虑使用原型模式拷贝多个对象供调用者使用。

工厂方法(FactoryMethod)模式

  • 工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。

简单工厂

缺点:违背开闭,扩展不易

工厂方法

缺点:系统复杂度增加,产品单一

抽象工厂(AbstractFactory)模式



当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。

使用场景

  • NumberFormat、SimpleDateFormat

  • LoggerFactory

  • SqlSessionFactory:MyBatis

  • BeanFactory:Spring的BeanFactory(就是为了造出bean)

建造者(Builder)模式

创建的东西细节复杂,还必须暴露给使用者。屏蔽过程而不屏蔽细节

使用场景

  • StringBuilder:append()

  • Swagger-ApiBuilder

  • 快速实现。Lombok-Builder模式

结构型模式(Structural Pattern)

为什么用结构型模式

  • 结构型模式关注点“怎样组合对象/类?”所以我们关注下类的组合关系

  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的(继承)

  • 对象结构型模式关心类与对象的组合,通过关联关系在一个类中定义另一个类的实例对象(组合)

  • 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。

  • 适配器模式(Adapter Pattern):两个不兼容接口之间适配的桥梁

  • 桥接模式(Bridge Pattern):相同功能抽象化与实现化解耦,抽象与实现可以独立升级。

  • 过滤器模式(Filter、Criteria Pattern):使用不同的标准来过滤一组对象

  • 组合模式(Composite Pattern):相似对象进行组合,形成树形结构

  • 装饰器模式(Decorator Pattern):向一个现有的对象添加新的功能,同时又不改变其结构

  • 外观模式(Facade Pattern):向现有的系统添加一个接口,客户端访问此接口来隐藏系统的复杂性。

  • 享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象

  • 代理模式(Proxy Pattern):一个类代表另一个类的功能

适配器模式(Adapter Pattern)

将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,适配器模式分为类结构型模式(继承)和对象结构型模式(组合)两种,前者(继承)类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

适配器模式(Adapter)包含以下主要角色。

  • 目标(Target)接口:可以是抽象类或接口。客户希望直接用的接口

  • 适配者(Adaptee)类:隐藏的转换接口

  • 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口。

类结构型

对象结构型

使用场景

  • Tomcat如何将Request流转为标准Request;

    • tomcat.Request接口
    • servlet.Request接口
  • Spring AOP中的AdvisorAdapter是什么:增强的适配器

    • 前置、后置、返回、结束 Advisor(通知方法)
  • Spring MVC中经典的HandlerAdapter

桥接模式(Bridge Pattern)

  • 将抽象与实现解耦,使两者都可以独立变化

  • 桥接将继承转为关联,降低类之间的耦合度,减少代码量

桥接(Bridge)模式包含以下主要角色。

  • 系统设计期间,如果这个类里面的一些东西,会扩展很多,这个东西就应该分离出来
  • 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  • 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  • 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。

使用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。

  • 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。

  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。

  • InputStreamReader桥接模式。An InputStreamReader is a bridge from byte streams to character streams:

  • InputStreamReader 桥接+适配器

过滤器模式(Filter、Criteria Pattern)

  • 使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。结合多个标准来获得单一标准

组合模式(Composite Pattern)

  • 把一组相似的对象当作一个单一的对象。如:树形菜单

使用场景

  • 层级结构

  • 部门组织结构

装饰器模式(Decorator/Wrapper Pattern)

  • 适配器是连接两个类,可以增强一个类,装饰器是增强一个类

  • 向一个现有的对象添加新的功能,同时又不改变其结构。属于对象结构型模式。

  • 创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

  • 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

  • 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。

  • 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

  • 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

使用场景

  • SpringSession中如何进行session与redis关联?HttpRequestWrapper

  • MyBatisPlus中QueryWrapper

  • Spring中的BeanWrapper是做什么?包装了Bean。bean的功能增强?

外观模式(Facade Pattern)

外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式

使用场景

  • JAVA 的三层开发模式

  • 分布式系统的网关

  • Tomcat源码中的RequestFacade

享元模式(Flyweight Pattern)

  • 运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。

  • 在享元模式中可以共享的相同内容称为内部状态(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。

  • 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。

使用场景

  • 数据库连接池

  • 大部分池化技术

代理模式(Proxy Pattern)

给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。这种是静态代理

  • JDK动态代理

  • cglib动态代理

  • 装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制,但不对对象本身的功能进行增强

使用场景

  • MyBatis的mappe,mybatis帮我们写实现MapperProxy

  • Spring AOP

行为型模式(Behavioral Patterns)

为什么用行为型模式

  • 行为型模式关注点“怎样运行对象/类?”所以我们关注下类/对象的运行时流程控制

  • 行为型模式用于描述程序在运行时复杂的流程控制,

  • 描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。

  • 行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

  • 模板方法(Template Method)模式:父类定义算法骨架,某些实现放在子类

  • 策略(Strategy)模式:每种算法独立封装,根据不同情况使用不同算法策略

  • 状态(State)模式:每种状态独立封装,不同状态内部封装了不同行为

  • 命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开

  • 职责链(Chain of Responsibility)模式:所有处理者封装为链式结构,依次调用

  • 备忘录(Memento)模式:把核心信息抽取出来,可以进行保存

  • 解释器(Interpreter)模式:定义语法解析规则

  • 观察者(Observer)模式:维护多个观察者依赖,状态变化通知所有观察者

  • 中介者(Mediator)模式:取消类/对象的直接调用关系,使用中介者维护

  • 迭代器(Iterator)模式:定义集合数据的遍历规则

  • 访问者(Visitor)模式:分离对象结构,与元素的执行算法

  • 除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式

模板方法(Template Method)模式

  • 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

使用场景

  • Spring的整个继承体系都基本用到模板方法;BeanFactory.getBean(1,2,3,4)--A1---A2---A3---A4(全部被完成)

  • JdbcTemplate、RedisTemplate都允许我们再扩展

策略(Strategy)模式

  • 定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。属于对象行为模式。

  • 抽象策略(Strategy)类:公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

使用场景

  • 使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句
  • 线程池拒绝策略

状态(State)模式

  • 对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为

  • 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。

  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。

  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

使用场景

  • 流程框架与状态机
  • 状态模式核心需要具体状态类能在必要的时候切换状态

中介者(Mediator)模式

  • 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,减少对象间混乱的依赖关系,从而使其耦合松散,而且可以独立地改变它们之间的交互。对象行为型模式。



使用场景

  • SpringMVC 的 DispatcherServlet是一个中介者,他会提取Controller、Model、View来进行调用。而无需controller直接调用view之类的渲染方法

  • 分布式系统中的网关

  • 迪米特法则的一个典型应用

  • 中介者和外观(门面)模式区别:中介者双向操作,门面偏向于封装某一方

观察者(Observer)模式

  • 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。对象行为型模式

  • Subject: 目标
  • ConcreteSubject: 具体目标
  • Observer: 观察者
  • ConcreteObserver: 具体观察者

使用场景

  • Spring事件机制

  • Vue的双向绑定核心

  • 响应式编程核心思想

备忘录(Memento)模式

  • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。对象行为型模式

  • 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

  • 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

  • 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

使用场景

  • 游戏存档

  • 数据库保存点事务(savepoint)

  • session活化钝化

解释器(Interpreter)模式

  • 给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。类行为型模式

  • 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。

  • 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。

  • 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。

  • 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。

  • 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

使用场景

  • Spring的表达式解析:#{}

  • Thymeleaf等模板引擎的语法解析

  • 编译原理

  • 编译器

  • execution(* com..(int,..))

命令(Command)模式

  • 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

命令模式包含以下主要角色。

  • 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。

  • 具体命令类(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。

  • 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。

  • 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

使用场景

  • mvc就是典型的命令模式

  • 当系统需要执行一组操作时,命令模式可以定义宏命令(一个命令组合了多个命令)来实现该功能。

迭代器(Iterator)模式

  • 提供一个对象(迭代器)来顺序访问聚合对象(迭代数据)中的一系列数据,而不暴露聚合对象的内部表示。对象行为型模式

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。

  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。

  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

使用场景

  • jdk容器接口的Iterator定义

  • 现实开发中,我们几乎无需编写迭代器,基本数据结构链表、树、图的迭代器已经都有了。除非要重写迭代逻辑

访问者(Visitor)模式

  • 将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

  • 抽象访问者(Visitor)角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素。

  • 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。

  • 抽象元素(Element)角色:声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数。

  • 具体元素(ConcreteElement)角色:实现抽象元素角色提供的 accept() 操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。

  • 对象结构(Object Structure)角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。

使用场景

  • 在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”

  • 违反依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类

  • 破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性

  • Spring反射工具中的 MethodVisitor

职责链(Chain of Responsibility)模式

  • 为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。属于对象行为型模式

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

使用场景

  • Tomcat的Pipeline、Valve

  • Spring Aop责任链

框架源码里面的设计模式

Spring

  • 创建型

    • 单例(Singleton)模式

      • Spring借鉴单例模式思想,但是将所有需要单例的Bean放在工厂的单例池中。在DefaultSingletonBeanRegistry的singletonObjects这个Map中
    • 原型(Prototype)模式

      • Spring借鉴原型模式思想,但是将所有多实例的的Bean获取,都动态调用工厂进行创建新对象操作
    • 工厂方法(FactoryMethod)模式

      • Spring的BeanFactory属于工厂方法模式+模板模式
    • 抽象工厂(AbstractFactory)模式

    • 建造者(Builder)模式

      • aop,建造出增强器的builder
  • 结构型

    • 代理(Proxy)模式

      • cglib动态代理,Configuration配置类创建的都是代理对象
      • PostProcessorRegistrationDelegate:代理PostProcessor的执行
      • DelegatingMessageSource:代理国际化信息的执行
    • 适配器(Adapter)模式

      • adaptBeanInstance():bean创建完成以后连接Object类型和T类型
    • 桥接(Bridge)模式

      • 分离了工厂(BeanFactory)与工厂功能增强(BeanFactoryPostProcessor),利用PostProcessorRegistrationDelegate连接BeanFactory的初始化过程和BeanFactoryPostProcessor的增强过程
    • 装饰(Decorator)模式

      • BeanWrapper
      • BeanHolder
      • PropertyValue;装饰了属性名和值,增强了利用反射赋值
      • ......
      • InjectedElement(通过分析所有方法或者属性找到标注@Autowired等注解的,然后封装为IE)
    • 外观(Facade)模式

      • DispatcherServlet,处理所有请求然后进行匹配映射
    • 享元(Flyweight)模式

      • Spring是使用享元完成单例模式
        使用单例对象池(单例享元池返回组件)
        DefaultSingletonBeanRegistry==》singletonObjects
    • 组合(Composite)模式

      • DOM解析xml的时候,父元素和子元素等属于组合关系

      • Spring大量都是组件

        • Spring继承就来做子类对父类的功能增强
        • Spring大量使用组合,引用一些分离出来的功能
  • 行为型

    • 模板方法(Template Method)模式

      • Spring的BeanFactory整个都是模板模式
      • Spring中的层级接口与实现都是模板模式
    • 策略(Strategy)模式

      • Spring进行xml等资源处理的时候

        • ResourceLoader代表资源加载器,底层有各种资源器的实现类,来实现不同的资源加载办法,最终加载出Resource
        • 而AbstractApplicationContext作为环境类引用了 ResourcePatternResolver (也是ResourceLoader接口下的),通过创建不同的资源加载策略,而实现不同的加载功能
      • Spring对Bean进行对象创建的时候

        • Spring定义了InstantiationStrategy 接口,用来创建bean的对象

          • SimpleInstantiationStrategy(无参构造器初始化策略)
          • CglibSubclassingInstantiationStrategy(cglib初始化策略)
        • AbstractAutowireCapableBeanFactory ,bean工厂在创建bean的时候动态的根据bean是否需要代理而使用不同的策略

      • Converter:类型转换

        • 底层很多的converter类型转换器
        • 根据当前需要转换的类型决定使用哪个转换器
        • 调用转换器的转换方法
    • 命令(Command)模式

      • 方法封装都算命令模式
    • 职责链(Chain of Responsibility)模式

      • AOP链式调用
      • BeanPostProcessor:保存所有的后置处理器,挨个进行执行(for)
    • 状态(State)模式

      • Tomcat底层、每一个组件都有状态流转的方法
    • 观察者(Observer)模式

      • ApplicationListener事件监听
    • 中介者(Mediator)模式

    • 迭代器(Iterator)模式

      • PropertyValues定义了迭代PropertyValue的方法
    • 访问者(Visitor)模式

      • WebMvcConfigurer就是
    • 备忘录(Memento)模式

      • 状态提取出来进行保存
    • 解释器(Interpreter)模式

      • Spring解析表达式,${ },迭代解析

Tomcat

  • 门面模式

Tomcat 中门面设计模式使用的很多,因为 Tomcat 中有很多不同组件,每个组件要相互交互数据,用门面模式隔离数据是个很好的方法。

HttpRequestFacade 类封装了 HttpRequest 接口能够提供数据,通过 HttpRequestFacade 访问到的数据都被代理到 HttpRequest 中,通常被封装的对象都被设为 Private 或者 Protected 访问修饰,以防止在 Façade 中被直接访问。

  • 观察者模式

Tomcat的组件生命周期状态只要一变化,Tomcat就会通知改组件的所有的观察者,把状态变化通知到所有的观察者,看是否有观察者对相关组件的状态变化感兴趣。

  • 模版模式

Tomcat中的模版设计模式就是把公共的动作抽象到父类中,在父类的方法中调用一些抽象方法,而这些抽象方法留给子类去实现,从而完成公共动作和特殊动作的分离。

  • 责任链模式

Tomcat内部的Pipeline 机制

  • 命令模式

命令模式在Tomcat中主要是应用在对请求的处理过程中

posted @ 2021-11-07 18:55  xmz_pc  阅读(175)  评论(0编辑  收藏  举报