设计模式是面对特定业务场景时的一种开发套路。它源于生活,通常我们能找到相应的例证,但高于生活(抽象),它能解决一类问题。使用设计模式的根本目标是开发时尽可能遵循面向对象的设计原则,不可生搬硬套,一切随缘(重构/优化)。
设计原则(SOLID):单一职责、开闭原则、里氏替换、依赖倒转、迪米特法则(最小知识法则)、组合/聚合(通常来代替继承,关联关系在代码中表现为类中一个属性引用,如private HandSoft soft)。
常用的设计模式有23中,分为三大类。
创建型:创建对象。结构型:更大,更复杂的结构。行为型:对象的交互问题。
简单工厂:工厂就是创建对象的,一般和多态一起使用(比如一个父类有多个子类)。在客户端需要指定创建哪个对象。
工厂方法模式:工厂类不直接创建对象,交给它的工厂子类去完成。
抽象工厂模式:和工厂方法类似,只不过是创建多种类型对象。
类别 | 名称 | 描述 | 速记词 |
创建型 | 工厂方法模式 | 定义一个创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到子类。 | 创建一种类型对象 |
抽象工厂模式 | 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 | 创建多种类型对象 | |
单例模式 | 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 | 唯一对象 | |
原型模式 | 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 | 对象克隆 | |
建造者模式 | 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 | 复杂对象(创建游戏人物) | |
结构型 | 代理模式 | 为其他对象提供一种代理以控制对这个对象的访问。 | 面向切面编程(aop) |
适配器模式 | 将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 | 转换接口 | |
桥接模式 | 将抽象部分与实现部分分离,使它们都可以独立的变化。 | 抽象和实现分离,防止类爆炸(实现类过多),是组合/聚合原则的实践 | |
组合模式 | 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 | 整体,部分操作具有一致性(文件目录结构、Mybaitis中SqlNode实现) | |
装饰模式 | 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。 | 对象增强(io流) | |
外观模式 | 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 | 统一外观(防止同一层级service相互调用) | |
享元模式 | 运用共享技术有效地支持大量细粒度的对象。 | 对象复用(word中的字符,围棋中的棋子,spring中管理的对象默认是单例的这就是一种对象共享机制。) | |
行为型 | 观察者模式 | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 | 发布-订阅、生产者-消费者、mq、excel(A3=A1+A2) |
模板方法模式 | 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 |
1.各种需要填写的模板文件(部分需要填写) 2.外部接口调用封装(调用规则一致,参数部分不一致) | |
命令模式 | 将一个请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化。对请求排队或记录日志,以及支持可撤销的操作。 | 日志记录,撤销(点餐流程:客户->服务员->点餐(命令)->厨师) | |
状态模式 | 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。 |
减少大量条件分支,将行为独立出来了(状态影响行为)。 酒店房间预定、活字印刷 | |
职责链模式 | 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。 | 传递职责链,各司其职 | |
解释器模式 | 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 | jvm | |
中介者模式 | 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 | 对象间不直接引用,将对象间的网状联系变为星型联系(中介处于中心) | |
访问者模式 | 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 |
数据和操作分离。 (如销售数据,销售员,主管,经理等不同的人对数据的使用行为不同) | |
策略模式 | 定义了算法家族,分别封装起来,让它们之间可以相互替换。此模式让算法的变化,不会影响到使用算法的客户。 | 不同算法之间的替换 | |
备忘录模式 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。 | 游戏存档 | |
迭代器模式 | 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。 | Iterator 提供各种访问内部对象的操作 |