单例模式
-
保证只有一个对象,用过public static Foo insFoo = null 实现
-
通过static Foo getInstance(){ … }来创建和返回实例
-
多线程优化
synchronized getInstance
直接在静态初始化时创建对象
getInstance双重检查( synchronized(Foo.class) 作为同步区,insFoo声明为volatile)
策略模式
(接口)
一个上下文持有某一种策略 (和状态模式正好有点相反的感觉)
上下文对象策略的选择由客户决定,一般用于各个算法实现。
-
对象中持有某个 策略 对象, 该对象是某个接口,具有多个实现(不同策略),同时可以动态的对对象持有的策略进行修改。
-
Context.do_action(), 注重在策略
状态模式
(接口)
一个状态持有上下文对象(即每次执行动作需要将状态传入)
- 每个状态下的行为是完全的。
- 状态的变化一般都要进行的(或者说轮换?),而策略需要选择。(更像是过程式编程)
- 每个状态的操作中也可以改变上下文对象持有的状态,例如打篮球的时候运动员可以有正常状态、不正常状态和超常状态
- doAction(Context), 注重要状态的改变
模板模式
(继承)
动作的顺序,逻辑形成模板(过程式编程思想),是固定的。具体的每一个动作由子类实现。
工厂模式
使用工厂来控制对象的初始化过程,到达对象定制。
- 控制产品的生产和拓展
产品
- 产品接口1 - 产品1.1 - 产品1.2
- 产品接口2 - 产品2.1 - 产品2.2
简单工厂
- 产品工厂1 - create_产品接口1
- 产品工厂2 - create_产品接口2
可以拓展工厂3,4, 也可以在工厂中拓展create_产品接口3
抽象工厂:
对应:产生一系列的产品(解决工厂泛滥问题)
工厂基类(接口)
- 工厂1 - create_产品接口1, create_产品接口2
- 工厂2 - create_产品接口1, create_产品接口2
缺点:抽象工厂(基类)对应新的产品时,需要拓展(需要在接口-基类,和子类中都新增该新产品)
例如: 新增产品接口3
那么需要在工厂基类中新增抽象方法,而所有子类工厂都需要实现该方法。
Spring Bean工厂
建造者模式
- 旨在对复杂对象的组装。
- 利用不同的Builder构建不同的组成对象。
- 这么看的话,比抽象工厂适用更广啊,工厂是为了控制原对象的生成过程,而不负责组装
访问者模式
不需要对对象进行修改,只需要该具体的操作即可。
- 观察者是被动的接受通知,操作在被观察者中,当然也可以写在观察者中,这样就暴露信息了。
- 而访问者是主动的访问, 操作在访问者中
观察者模式
(继承,数组)
Observable 和 Observer
- 在Observable中注册观察者,通知观察者等。
- java自带了两个基类(不过java 9已经弃用)
责任链模式
(继承,链表递归的逻辑)
与观察者类似,但是像链表一样,是一级一级的,而不是像观察者一样是扩散式的。
装饰器模式
接口
public interface Fooable{
void run();
}
接口实现的对象
public class Foo implements Fooable{
@Override
void run() { do something;};
}
- 一般是对接口(可能)的聚合,对接口实现对象的方法进行拓展。
- 同时可以多个装饰器,多次嵌套(所以通过接口实现,注意下面的数据域)
class FooDecoratorTimer implements FooInterface{
private FooInterface afoo;
public FooDecoratorTimer(FooInterface foo){
// 聚合
this.afoo = foo;
}
@Override
void run() {
before();
do something;
};
}
class FooDecoratorLogger implements FooInterface { ... }
代理模式
有点像装饰器,通过聚合方式来操控代理对象。
- 一般是具体的对象(也可以是接口),对对象的功能进行拓展和新增。
- 数据域: InterfaceObject_1(表示实现了接口的某个对象类) aObj = null
- 区别,一个强力的人(代理) 和 一个团队(装饰器)
class Fooproxy implements FooInterface{
private Foo afoo;
public FooDecoratorTimer(Foo foo){
// 聚合
this.afoo = foo;
}
@Override
void run() {
before();
do something;
};
public void newfunction_1(){ ... }
public void newfunction_2(){ ... }
}
动态代理
运行时,动态生成代码,生成相应的代理Class
可以对任意对象,任意的接口方法实现任意代理(使用handler)。
外观模式
多个系统,通过一个新的接口来实现聚合多个子系统,以减少客户端的代码目的。
桥模式
对于多维的概念,例如咖啡有大杯,小杯, 可以加糖,不加糖
使用桥模式在结构上衔接,实现组合
例如
- 大杯加糖,价格 = 大杯咖啡 + 2倍糖价格
- 小杯加糖: 价格 = 小杯咖啡 + 1倍糖价格