- 创建型模式:对象的创建与使用分离,不需要关注对象的创建细节,这样可以降低系统的耦合度
- 结构型模式:或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象;由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性
- 行为模式:描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配;行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性
Spring常用的设计模式:
- 工厂模式:只对结果负责,封装创建过程
- BeanFactory(简单工厂模式)
- 单例模式:保证独一无二
- ApplicationContext,@Component
- 原型模式:可以复制千千万万
- PrototypeBean
- 代理模式:找人办事,增强职责
- ProxyFactoryBean、JdkDynamicAopProxy、CglibAopProxy
- 委派模式:干活算你,功劳算我
- DispatcherServlet、BeanDefinitionParserDelegate
- 策略模式:用户选择,结果统一
- InstaniationStragegy
- 模版模式:流程标准化,自己实现定制
- JdbcTemplate、RestTemplate
- 适配器模式:兼容转换头
- AdvisorAdapter、HandlerAdapter
- 装饰者模式:包装,同宗同源
- InputStreamSource、EncodedResource、HttpHeadResponseDecorator
- 观察者模式:在任务完成时通知
- ContextLoaderListener
- 简单工厂模式
- 优点:面向对象编程思想,屏蔽代码实现,工厂面向所有调用者
- 缺点:新增一个产品的话会对代码进行重写,不符合OCP开闭原则
- 工厂方法模式
- 优点:满足里氏替换原则、迪米特法则、开闭原则;灵活型强,新产品只要新增一个工厂实现类就好
- 缺点:工厂实现类的个数随着时间推移会增多,增加复杂度;只能生产一种产品(游戏类),此弊端可以用抽象工厂解决
- 抽象工厂模式
- 优点:一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象(将一个系列的产品统一一起创建);
- 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要修改工厂抽象类里加代码,又修改具体的实现类里面加代码;增加了系统的抽象性和理解难度
- 适用于:定义好产品族系列产品不变,产品级别可变的情况
三、单例模式
单例模式需要构造方法私有化,提供公共静态方法获取单例对象
- 饿汉模式
- 每次new一个对象
- 赖汉模式
- 原则上只new一次对象,多线程可能出现线程安全问题;可以通过同步法则规避此问题
每次都是new一个对象
五、建造者模式建造者(Builder)模式的主要角色如下:
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
和工厂模式的区别:
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。
- 创建复杂对象,就可以考虑使用建造者模式
- 静态代理
由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了,同时目标类需要实现父接口
很明显如果女人改变了,媒人也需要修改信息,违背了OCP开闭原则
- JDK动态代理
运行时在内存动态创建代理,利用jdk自带的Proxy工具创建代理,并且实现InvocationHandler接口,而且目标类需要实现父接口或继承父类
- cglib动态代理
也是在运行时内存动态创建代理类或实现接口,目标类不用实现或继承类,又叫子类代理,代理类是目标类的子类,比如springAop中的ObjenesisCglibAopProxy代理实现
七、适配器模式
适配器
- 模式特点
- 适配器模式(Adapter)包含以下主要角色。
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
- 类适配:继承适配者使自己成为适配者,不提倡
- 组合适配:委派式调用,更灵活
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
桥接(Bridge)模式包含以下主要角色:
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
装饰器模式主要包含以下角色:
- 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式包含以下主要角色:
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
享元模式的定义提出了两个要求,细粒度和共享对象。因为要求细粒度,所以不可避免地会使对象数量多且性质相近,此时我们就将这些对象的信息分为两个部分:内部状态和外部状态。
- 内部状态指对象共享出来的信息,存储在享元信息内部,并且不会随环境的改变而改变;
- 外部状态指对象得以依赖的一个标记,随环境的改变而改变,不可共享,可以动态注入。
享元模式的主要角色有如下:
- 抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
- 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
- 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
- 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
组合(Composite Pattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构设计模式。
层层嵌套,类似与链表结构;整体-部分结构中部分数目不宜过多,特别是部分如果差别很大,使结构复杂,不易读难维护;不容易使用继承增加构建新方法。
组合模式包含以下主要角色。
- 抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)
- 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。
- 树枝构件(Composite)角色 / 中间构件:是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
代码大致这样......
- 定义观察目标对象Wallet
package com.demon.design.observer;
import java.util.ArrayList;
import java.util.List;
public class Wallet {
private List observers = new ArrayList<>();
private double money;
public void addObserver(PaymentObject observer) {
observers.add(observer);
}
public void removeObserver(PaymentObject observer) {
observers.remove(observer);
}
public void setState(int state) {
// 进账了...
notifyAllObservers();
}
private void notifyAllObservers() {
for (PaymentObject paymentObject : observers) {
paymentObject.phoneTooltip();
}
}
}
- 定义 观察者抽象类PaymentObject
package com.demon.design.observer;
public abstract class PaymentObject {
protected Wallet wallet;
public abstract void phoneTooltip();
}
- 银行扩展了观察者 PaymentObject,设置PaymentBank观察者实体类
package com.demon.design.observer;
public class PaymentBank extends PaymentObject{
public PaymentBank(Wallet wallet) {
this.wallet = wallet;
this.wallet.addObserver(this);
}
@Override
public void phoneTooltip() {
System.out.println("你钱包有一笔钱新入账,可以还钱给工商银行了吧!");
}
}
- 妻子扩展了观察者 PaymentObject,设置PaymentWife观察者实体类
package com.demon.design.observer;
public class PaymentWife extends PaymentObject{
public PaymentWife(Wallet wallet) {
this.wallet = wallet;
this.wallet.addObserver(this);
}
@Override
public void phoneTooltip() {
System.out.println("你钱包有一笔钱新入账,可以上交给老婆了吧!");
}
}
- 儿子扩展了观察者 PaymentObject,设置PaymentChildren观察者实体类
package com.demon.design.observer;
public class PaymentChildren extends PaymentObject{
public PaymentChildren(Wallet wallet) {
this.wallet = wallet;
this.wallet.addObserver(this);
}
@Override
public void phoneTooltip() {
System.out.println("你钱包有一笔钱新入账,可以给儿子交学费了吧!");
}
}
- 建立服务,运行程序......
package com.demon.design.observer;
public class MainRunner {
public static void main(String[] args) {
Wallet wallet = new Wallet();
PaymentObject paymentBank = new PaymentBank(wallet);
PaymentObject paymentWife = new PaymentWife(wallet);
PaymentObject paymentChildren = new PaymentChildren(wallet);
// 钱包入账了...
wallet.setState(100);
// 通知大佬们可以向我要钱了...
}
}
十四、策略模式你钱包有一笔钱新入账,可以还钱给工商银行了吧!
你钱包有一笔钱新入账,可以上交给老婆了吧!
你钱包有一笔钱新入账,可以给儿子交学费了吧
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式,在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
策略模式的主要角色如下:
- 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理
命令模式包含以下主要角色:
- 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
- 具体命令类(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
- 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
- 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。
迭代器模式(Iterator Pattern)用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。每次都需要新增容器实现类和迭代器实现类
迭代器模式主要包含以下角色:
- 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
- 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
- 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
- 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
使用场景:
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
职责链模式主要包含以下角色:
- 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
- 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
状态变化影响某一行为,比较鸡肋
二十、Reactor模式(I/O服务模型)Reactor 的叫法: 1. 反应器模式 2. 分发者模式(Dispatcher) 3. 通知者模式(notifier)
也叫多路复用路由监听处理



