- 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
- 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
- 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
设计模式原则
开放封闭原则
就是对扩展开放,对原有类的修改封闭。在不影响原有类的基础上进行拓展
里氏代换原则
子类型必须能够替换父类型,也就是父类型的功能可以被复用。
单一职责原则
一个类仅应该有一个引起他变化的原因。可拓展性高。
依赖倒置原则
高层模块和底层模块都应该依赖于抽象,细节应该依赖于抽象。
比如电脑内存条坏了,我们仅仅需要更换内存条就行了,而不需要把cpu也换了,类似于一种解藕的思想。
迪米特法则
如果两个类不必直接通信,则可以通过一个第三者去转发调用。降低耦合度。
合成复用原则
原则是尽量使用合成/聚合的方式,而不是使用继承。
常用的模式
简单工厂模式
拿经典的加减乘除来举例
- 我们需要先封装一个算法抽象类,定义方法。
- 然后定义加减乘除四个子类继承该抽象类,并实现
- 最后在创建一个算法工厂类,通过switch(运算符)来实现对应的算法。
抽象工厂模式
比如封装一个多数据源的访问。
- 新建一个接口,定义访问的方法。
- 然后各个数据库为其创建对应的类,实现该接口。
- 再定义一个工厂接口,实现对应对象创建的方法。
- 再定义几个类去实现该接口的方法。
- 可以实例化对应的工厂去使用。
工厂方法模式
还是拿经典的加减乘除来举例
- 我们需要先封装一个算法抽象类,定义方法。
- 然后定义加减乘除四个子类继承该抽象类,并实现
- 最后在创建一个工厂接口。
- 定义多种算法工厂类实现该接口,例如将基础算法归于一类,高级算法归于一类。
- 最后再拿一个算法工厂类通过switch(运算符)去实现对应的算法。
抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
将工厂抽象成两层,抽象工厂 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂集合, 更利于代码的维护和扩展。
装饰者模式
动态的给类添加一些额外的职责,就添加功能来说,该模式比生成子类更加灵活。
- 定义一个抽象类component
- concretecomponent类继承抽象类
- decorator继承了component的抽象类,可以从外部扩展component功能
- 定义具体装饰类继承decorator
- Component(抽象构件):定义一个对象接口,以规范准备接收附加责任的对象。
- ConcreteComponent(具体构件):实现Component接口,也就是给装饰者提供原始对象。
- Decorator(抽象装饰者):实现Component接口,持有对另一个Component对象的引用,并定义一个与Component接口一致的接口。
- ConcreteDecorator(具体装饰者):实现Decorator接口,给组件添加一些职责。
策略者模式
定义了算法策略,分别封装起来,让他们可以互相替换,不会影响到使用算法的客户。
- 定义一个算法抽象类
- 几个具体实现类
- 定义一个conext类,内部使用算法抽象类,实例化,并调用其的算法
- 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
- 上下文(Context)类:是使用算法的角色, 持有一个策略类的引用,最终给客户端调用。
模板模式(很简单)
定义一个算法骨架,将一些步骤延迟到子类中,使得子类不需要改变算法结构就可以重新定义某个步骤
- 一个抽象类
- 几个实现类
代理模式
为其他对象提供一种代理以控制该对象的访问
- 定义一个抽象类或接口
- 定义一个具体实现类继承该类
- 再定义一个具体代理类,并在内部将上一个具体类作为成员变量
动态代理与静态代理的区别就是代理类与被代理类有没有直接继承或实现的关系。
【设计模式】Java 的三种代理模式_创建代理对象的三大方式-CSDN博客
责任链模式
使多个对象都有机会去处理请求,从而避免请求的发送者和接收者的关系之前的耦合。将对象链接成一个链,并通过该链条传递该请求,直到有一个对象处理他。
- 定义一个父接口
- 实现多个子类,可以实现不同内容处理
- 通过链条方式将他们链接起来
- 先从底层开始处理
java设计模式---责任链模式详解_责任链模式 java-CSDN博客
Java设计模式-责任链模式_java责任链模式-CSDN博客
单例模式
保证一个类只有一个实例,并且提供一个访问他的全局访问点。
- 将类成员变量设置为静态
- 私有化其他构造方法,只留一个构造,且内部进行判断,如果已经实例化,则直接返回。
- 且在成员变量加volatile关键字
- 实例化成员变量时内部加上synchronized锁,防止并发创建多个实例。
- 或者采用静态初始化
代码示例
class Singleton{private static Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){return instance;}}
或者
class Singleton{private volatile static Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){if(instance==null){synchornized(Singleton.class){if(instance==null){instance=new Singleton();}}}return instance;}}
创建型模式
工厂方法模式
与简单工厂方法比较类似,在简单工厂基础上进行了二次封装,让各类的职责更加明确。
还是拿经典的加减乘除来举例
- 我们需要先封装一个算法抽象类,定义方法。
- 然后定义加减乘除四个子类继承该抽象类,并实现
- 最后在创建一个工厂接口。
- 定义多种算法工厂类实现该接口,例如将基础算法归于一类,高级算法归于一类。
- 最后再拿一个算法工厂类通过switch(运算符)去实现对应的算法。
抽象工厂模式
比如封装一个多数据源的访问。
- 新建一个接口,定义访问的方法。
- 然后各个数据库为其创建对应的类,实现该接口。
- 再定义一个工厂接口,实现对应对象创建的方法。
- 再定义几个类去实现该接口的方法。
- 可以实例化对应的工厂去使用。
单例模式
保证一个类只有一个实例,并且提供一个访问他的全局访问点。
- 将类成员变量设置为静态
- 私有化其他构造方法,只留一个构造,且内部进行判断,如果已经实例化,则直接返回。
- 且在成员变量加volatile关键字
- 实例化成员变量时内部加上synchronized锁,防止并发创建多个实例。
- 或者采用静态初始化
class Singleton{private static Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){return instance;}}
或者
class Singleton{private volatile static Singleton instance = new Singleton();private Singleton(){}public static Singleton getInstance(){if(instance==null){synchornized(Singleton.class){if(instance==null){instance=new Singleton();}}}return instance;}}
建造者模式
将一个复杂对象的构建和他的表示分离,同样的建造过程可以创建不同的表示
比如产品类
- 先写一个抽象建造者类,把抽象方法都定义好
- 然后写几个具体建造者类继承抽象类
- 然后指导者类,内部构造去写一个调用抽象类的创建人的各个方法。
可以实现客户并不知道具体的建造过程
原型模式
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
- 封装一个抽象类实现cloneable接口,重写clone方法。
- 创建具体原型类继承抽象类
结构型模式
适配器模式
将一个类的接口转换为客户需要的另一个接口。该模式使原本接口不兼容而不能一起工作的类可以一起工作。
- 首先定义两个接口
- 然后定义一个适配器类继承并重写其中方法,并且定义另一个类作为变量,在重写方法中用到。
装饰器模式
动态的给类添加一些额外的职责,就添加功能来说,该模式比生成子类更加灵活。
- 定义一个抽象类component
- concretecomponent类继承抽象类
- decorator继承了component的抽象类,可以从外部扩展component功能
- 定义具体装饰类继承decorator
代理模式
为其他对象提供一种代理以控制该对象的访问
- 定义一个抽象类或接口
- 定义一个具体实现类继承该类
- 再定义一个具体代理类,并在内部将上一个具体类作为成员变量
外观模式
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,该接口使得该子系统更加容易使用。
- 定义四个子系统类
- 定义一个外观类,将四个子系统类全部实例化并写方法。
桥接模式
将抽象部分和实现部分相分离,使得他们可以独立的变化
- 定义一个抽象类
- 几个具体实现类
- 另一个抽象类 内部依赖第一个抽象类
- 具体类继承该抽象类
组合模式
将对象组合成树形结果表示部分-整体结构。使得用户对单个对象和组合对象的使用具有一致性。
- 定义一个component
- 定义两个子类leaf和composite
享元模式
运用共享技术有效的支持大量细粒度的对象
- 定义一个抽象类,几个具体类
- 再定义一个抽象工厂,内部依赖抽象类
行为型模式
策略模式
定义了算法策略,分别封装起来,让他们可以互相替换,不会影响到使用算法的客户。
- 定义一个算法抽象类
- 几个具体实现类
- 定义一个conext类,内部使用算法抽象类,实例化,并调用其的算法
模板方法模式
定义一个算法骨架,将一些步骤延迟到子类中,使得子类不需要改变算法结构就可以重新定义某个步骤
- 一个抽象类
- 几个实现类
观察者模式
定义了一种一堆多的关系,让多个观察者同时监听某个对象,该对象发生变化,会通知观察者对象去更新自己。
- 定义通知者抽象类接口,内部使用了观察者类
- 定义具体通知者
- 定义观察者抽象类接口,内部有更新方法
- 几个具体观察者类
迭代子模式
提供一种方法顺序访问一个聚合对象的各个元素,不暴露该对象的内部表示。
- 定义一个聚合抽象类
- 具体实现类
- 定义一个iterator迭代器抽象类
- 再定义一个具体类
- 就可以实现使用该迭代器去遍历具体聚合类
责任链模式
使多个对象都有机会去处理请求,从而避免请求的发送者和接收者的关系之前的耦合。将对象链接成一个链,并通过该链条传递该请求,直到有一个对象处理他。
- 定义一个父接口
- 实现多个子类,可以实现不同内容处理
- 通过链条方式将他们链接起来
- 先从底层开始处理
命令模式
将请求封装为对象,用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持撤销的操作。
- 定义一个命令接口,内部调用一个接收者类
- 定义接收者
- 定义具体命令类
- 定义invoker类,内部调用命令类
- 实例化接收者,实例化命令
- 实例化invoker,执行方法。
备忘录模式
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存该状态,这样以后就可将该对象恢复到原先保存的状态。
- 发起人 调用备忘录
- 备忘录
- 管理类 管理备忘录
状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
- 状态抽象类
- 几个具体状态类
- 一个上下文类
访问者模式
表示一个作用于某对象的元素的操作,他可以使在不改变元素情况下定义作用与这些元素的新操作
- 访问者
- 元素类
- 对象结构类
中介者模式
用一个中介来封装交互的动作。
- 定义一个抽象人 内部含中介
- 再定义两个具体人
- 然后定义一个中介
- 定义几个具体中介
- 通过实例化中介和人,给人设置相同中介就可以交互
解释器模式
给一个语言,定义他的一种表示,并定义一个解释器,用于解释
- 上下文类
- 抽象表达类
- 具体实现
推荐书籍:大话设计模式,清华出版社的,写的真的很不错!