24种设计模式 极简笔记
2019-01-05 本文已影响492人
BzCoder
相关资料以及注意事项:
- 本篇文章只做一些最精简的小结,具体实现代码见Sample GitHub帮助更深入的理解。
- 详细内容看参考菜鸟课程。
总体:
- 创建型
单例模式 简单工厂模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 - 结构型
代理模式 适配器模式 装饰器模式 桥接模式 组合模式 享元模式 外观模式 - 行为型
观察者模式 模板模式 命令模式 状态模式 职责链模式 解释器模式 中介者模式 访问者模式 策略模式 备忘录模式 迭代器模式
六大原则:
- 单一职责原则
一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。 - 开闭原则
一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。 - 里氏代换原则
所有引用基类(父类)的地方必须能透明地使用其子类的对象。 - 依赖倒转原则
抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。 - 接口隔离原则
使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。 - 迪米特法则
一个软件实体应当尽可能少地与其他实体发生相互作用。
工厂模式 Factory
- 简单工厂模式:一个工厂类生产全部,可以用反射实现。
- 工厂模式:一个产品一个工厂类,所有产品继承同一个接口。
- 抽象工厂模式:多个产品,同生产线产品在一个工厂类中生成,不同生产线不同工厂类。
单例模式 Singleton
- 懒汉式
- 双重锁 + volatile 保证线程安全,volatile防止指令重排序。
- 饿汉式
- 静态内部类
- 枚举 :防止序列化以及反射破坏单例
- static final 变量
static final 变量的饿汉式可以通过添加以下方法防止序列化破环单例 。
/**
* 涉及序列化和反序列化会破坏单例模式
* @return
*/
private Object readResolve(){
return instance;
}
在构造函数函数中添加以下判断防止反射破坏单例。
public HungrySingleton() {
if(instance!=null){
throw new RuntimeException("单例构造器禁止反射");
}
}
建造者模式 Builder
- 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
- 在Idea中可以安装InnerBuilder插件直接生成建造者模式。
原型模式 Prototype
适用对象构造时间消耗大的场景。通过实现clonable接口实现。
- 深拷贝 :引用对象必须层层调用clone来保证对象是彼此独立的。
- 浅拷贝: 应用对象指向同一个对象。
外观模式 门面模式 Facade
创建一个外观类来管理多个子系统,客户通过访问门面类来调用多个子系统,客户绝对不和子系统之间有交互。
装饰者模式 Decorator
在不改变原有对象的基础之上,将功能附加到对象上。一般基于接口或者一个抽象类。数据可以叠加积累。
适配器模式 Adapter
- 类适配器:通过实现接口实现。
- 对象适配器:通过对象组合实现。
享元模式 Flyweight
- 提取公共元素(内部参数),留下可变元素(外部参数),相当于是建立了一套缓存。
- 例子:Interger:-128~127之间有缓存,new出来对象地址是相同的。
组合模式 Composite
- 把一组相似的对象当作一个单一的对象,也就是说有统一的接口实现或者抽象父类。
- 建立自己类型的对象组,建立树形结构。可以用于建立文件树形结构。
桥接模式 Bridge
- 让多个不同的类可以排列组合,以防止类数目爆炸,两个类可以独自扩展。
代理模式 Proxy
- 静态代理
- JDK动态代理:通过接口中的方法名,在动态【生成新的】的代理类中调用业务实现类的同名方法,实现InvocationHandlerj接口
- CGLib动态代理:通过继承业务类,生成的动态代理类是业务类的【子类】,通过重写业务方法进行代理。
如果对象没有实现接口,就必须使用CGLib实现动态代理。CGLib不能对final修饰的类进行代理。
模板模式 Template
- 将通用算法抽象出来,排列一定的执行的顺序,具体到子类慢慢实现。为防止恶意操作,一般模板方法都加上 final 关键词。
迭代器模式 Iterator
- 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
策略模式 Strategy
- 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,需要的时候传入即可。
解释器模式 Interpreter
- 用的很少,自定规则去解析输入的数据。实际使用:正则表达式,Spring的EL表达式, SQL 解析。
观察者模式 Observer
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 观察者和被观察者是抽象耦合的。建立一套触发机制,一般采用异步模式。JDK,guava都提供了解决方案
备忘录模式 Memento
- 使用一个存储来存储数据的多个状态,可以存入或者取出,相当于后悔药的作用。用于存档,ctri + z,后退,数据库的事务管理。
命令模式 Command
- 通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。抽象命令,传入接受者,将组合好的命令传入调用者执行。
中介者模式 Mediator
- 将多对多的关系,通过中介者方法,把其转化为一对一的关系。例如:MVC结构中的C,聊天室用户发送消息。
责任链模式 Chain of Responsibility
- 每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。以此来一层一层的对请求进行处理。
访问者模式 Visitor
- 创建一个访问者类,在访问者类中定义我们的数据的不同取用方法。也就是我们把需要的原材料给到(访问者的accept方法)访问者,具体如何处理原材料是由访问者自己决定的。
状态模式 State
- 对于同一个接口,我们有多种不同的实现,我们可以把每一个实现类看成是一个状态。在控制实体类时,我们借上下文(Context)来进行不同实现类之间的切换。