设计模式简单汇总

2021-08-27  本文已影响0人  Atomic

创建型模式

静态工厂方法模式(Factory、Product、ConcreteProduct)

优缺点:抽象工厂制作,不需要知道产品细节;单一工厂制造产品,风险大

组成:

Factory(抽象类)

Product(抽象类,指定产品配方)

ConcreteProduct_A(具体产品类,继承自Produce)

ConcreteProduct_B(具体产品类,继承自Produce)

Factoryfactory=newFactory();

factory.createProducteA();

factory.createProducteB();

抽象工厂方法模式(Factory、ConcreteFactory、Product、ConcreteProduct)

优缺点:抽象工厂,产出产品族,分担风险,各司其职;增加类的个数,维护变难

组成:

Factory(接口,定义需要制作的规则)

ConcreteFactory_A(实现了Factory接口,制造A产品的规则,假如A产负责生产OPPO手机)

ConcreteFactory_B(实现了Factory接口,制造A产品的规则,假如A产负责生产ViVO手机)

Product(抽象类,抽象产品的定义)

ConcreteProduct_A_C(具体的产品,假如是 OPPO 手机的屏幕)

ConcreteProduct_B_C(具体的产品,假如是 ViVO 手机的屏幕)

ConcreteProduct_A_D(具体的产品,假如是 OPPO 手机的电池)

ConcreteProduct_B_D(具体的产品,假如是 ViVO 手机的电池)

建造者模式(Builder、ConcreteBuilder、Director、Product)

优缺点:只需要关注具体建造者,不必关注产品内部;适合产品内部细节不会太多变化,例如:1.人物换装,2.地图天气变化等

组成:

Builder(抽象类,确认了产品制作的规则,例如:需要各个零件拼接)

ConcreteBuilder (普通Class,1. 继承自 Builder,2. 构造函数,初始化产品类,3. 重写规则方案,修改产品内容)

Director指挥者 (普通Class,指挥者角色,拥有Builder参数,调用Builder方法,可以不存在)

Product (普通Class,存在具体的属性以及getter、setter方法)

工厂模式 和 建造者模式的 区别:

如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品

那么建造者模式就是一个 汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车

单例模式

优缺点:单例创建对象,节约资源

特点:私有构造函数(自己创建实例)静态私有成员变量(只有一个实例)静态公有的工厂方法(暴露实例)

饿汉单例模式(线程安全,不管样都创建,容易产生垃圾):

    publicstaticSingletoninstance=newSingleton();

    ……

publicstaticSingletongetInstance() {

returninstance;

   }

懒汉单例模式(线程不安全):

privatestaticSingletoninstance;

……

publicstaticSingletongetInstance() {

if(instance==null) {

instance=newSingleton();

   }

returninstance;

}

双重检查单例模式(JDK5版本以上使用,volatile)

    privatevolatilestaticSingletoninstance;

    ……

publicstaticSingletongetInstance() {

/**

* 第一次检查,防止不必要的加锁

*/

if(instance==null) {

synchronized(Singleton.class) {

    /**

    * 第二次检查,

    *   1. 针对指令重排,A线程可能只new了对象,只分配了内存地址,创建空对象,没有给对象赋初始值;解锁

    *   2. B线程等A线程解锁后,也进入了这个逻辑,先确认实例是否已经被A线程创建,因为volatile能看到对象状态

        */

if(instance==null) {

instance=newSingleton();

               }

           }

       }

returninstance;

   }

这种模式并不安全,对于JVM而言,它执行的是一个个Java指令。

在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。

但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。

即先赋值指向了内存地址,再初始化)这样就使出错成为了可能,我们仍然以A、B两个线程为例:

A、B线程同时进入了第一个if判断

A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

由于JVM内部的优化机制,JVM先划出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块

B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序

此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了

内部类单例模式(安全、不常用)

publicclassSingleton{

privateSingleton(){

   }

privatestaticclassSingletonContainer{

privatestaticSingletoninstance=newSingleton();

   }

publicstaticSingletongetInstance(){

returnSingletonContainer.instance;

   }

}

结构型模式

适配器模式(Target、Adaptee、Adapter、Client)

将原有的功能扩展,修改;类似转接头

Target(接口类型,制定规则)

Adaptee(普通Class,被适配者,有自己的方法)

Adapter(普通Class,适配者: 1.继承Adaptee,2.构造方法包含 adaptee,3.重写Adaptee的方法)

Targettarget=newAdaptee();

Targettarget=newAdapter();

两个对象中,Adapter会多一种方法,更加适配类似转接头

桥接模式(Abstraction、RefinedAbstraction、Implementor、ConcreteImplementor)

组合对象模式

Abstraction( 抽象类,构造函数中携带 Implementor 参数,并且定义抽象方法)

RefinedAbstraction_A(继承自Abstraction,说明它是一个维度,并实现抽象规则方法)

RefinedAbstraction_B(继承自Abstraction,说明它是一个维度,并实现抽象规则方法)

Implementor(接口类,有自己的规则;几分糖接口)

ConcreteImplementor_A(实现 Implementor,可以定义: 3分、5分糖的实现类)

ConcreteImplementor_B(实现 Implementor,可以定义: 3分、5分糖的实现类)

使用方:只要 Coffee coffee = new LargeCupCoffee(new FiveSugar());

装饰模式(Component、ConcreteComponent、Decorator、ConcreteDecorator)

扩展对象的功能,比继承灵活

Component(接口,定了规则)

ConcreteComponent(具体实现类,实现了Component)

Decorator(抽象类,1. 实现了 Component,2.构造函数,持有Component,3.抽象方法,调用 Component)

ConcreteDecoratorA (继承了 Decorator, 重写方法)

ConcreteDecoratorB(继承了 Decorator,重写方法)

ComponentconcreteComponent=newConcreteComponent();

ComponentcomponentA=newConcreteDecoratorA(newConcreteComponent());

ComponentcomponentB=newConcreteDecoratorB(newConcreteComponent());

外观模式(Facade、SubSystem)

子系统非常复杂,开发新功能,依赖原有代码;违背“开闭原则”

Facade(统一的门面类)

SubSystem(子系统类)

享元模式(Flyweight、ConcreteFlyweight、UnsharedConcreteFlyweight、FlyweightFactory)

减少内存中对象的数量,

Flyweight: 抽象享元类

ConcreteFlyweight: 具体享元类

UnsharedConcreteFlyweight: 非共享具体享元类

FlyweightFactory: 享元工厂类(map<String, Flyweight>),利用map来缓存

代理模式(Subject、Proxy、RealSubject)

通过中间代理,来做桥联;利于耗时请求延迟处理

Subject: (抽象类,request方法)

Proxy: (继承Subject,afterRequest、preRequest、request方法)

RealSubject: (继承Subject,request方法)

动态代理:

jdk:必须存在抽象的服务类(interface)

1. Proxy.newProxyInstance(classLoader, interface, invokeHandler(proxy, method, args))

cglib:可以不需要抽象的服务类,只需要存在实体类就行

1. Enhancer(实例化工具) , 2. 设置父类对象(Class类型)3. 回调函数, 4. 创建代理

行为型模式

命令模式(Command、ConcreteCommand、Invoker、Receiver)

宏命令,请求调用、请求接收解耦; 可能存在很多具体命令实现类

Command(接口,定义了可执行的命令,如:开、关)

ConcreteCommand(具体实现类,1. 实现了Command接口,2. 携带了接收者,Receiver)

Receiver(接收者,1. 具体实现方法)

Invoker(调用者,1.携带具体具体操作类,这样就控制了最终观察者)

中介者模式(Mediator、ConcreteMediator、Colleague、ConcreteColleague)

处理集中在具体中介者,各个对象之间的关系解耦

Mediator:( 抽象类,抽象中介者,1. 定义抽象方法,并注入 Colleague )

ConcreteMediator:(具体中介者, 1. 继承Mediator,2. 注入具体同事类, 3. 实现抽象方法,采用不同的同事类)

Colleague:(抽象类,抽象同事类,1.定义抽象方法,2. 构造函数,注入Mediator, 3.定义抽象,通知方法)

ConcreteColleague:(具体同事类,1. 注入Mediator, 2.重写通知方法,使用注入的Mediator )

举例:武林门盟主,可以推送消息;具体中介者,(容纳了各个具体门派,用来处理逻辑);门派抽象类,具体门派类

观察者模式(Subject、ConcreteSubject、Observer、ConcreteObserver)

对象与对象之间的依赖关系,广播通信

Subject: (抽象类,目标,1.包含List<Observer>,2. 定义观察方法,用于改变观察者Observer的状态)

ConcreteSubject: (具体目标,1.实现 Subject 的方法,实际操作Observer)

Observer: (接口,观察者, 1.定义了 抽象类的改变规则)

ConcreteObserver: (具体观察者, 1.实现了 Observer ,具体改变规则方案)

状态模式(Context、State、ConcreteState)

一个对象在其内部状态改变时改变它的行为

Context:(环境类,1. 参入引入 State,2. 按照入参不同,模拟环境不同,返回不同具体状态 ConcreteState )

State:(接口,抽象状态类,定义了对象的状态规则)

ConcreteState:(具体状态类,1.实现了State,针对各个对象的状态行为)

策略模式(Context、Strategy、ConcreteStrategy)

一系列算法,将每一个算法封装起来,并让它们可以相互替换;客户端必须知道所有的策略类

Context: (普通类,环境类,1.注入策略类 Strategy 作参数 2. 构造函数注入 Stratege 3.具体实现方法,引用 Strategy 的方法)

Strategy: (接口,抽象策略类,指定算法类型,例:排序算法)

ConcreteStrategy: (普通Class,具体策略类,1. 实现Strategy,2. 例:冒泡排序、快速排序、堆排序……)

上一篇下一篇

猜你喜欢

热点阅读