定义:定义了一个算法的骨架,并允许子类为一个或多个步骤提现实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
适用场景:
1、一次性实现一个算法的不变的部分,并将可变的行为留给子类实现
2、各子类中公共的行为被提取出来并集中到一个公共父类中,从而避免代码重复
优点:
1、提高复用性
2、提高扩展性
3、符合开闭原则
缺点:
1、类数目增加
2、增加了系统实现的复杂度
3、继承关系自身的缺点,如果父类添加新的抽象方法,所有子类都要改一遍
开源框架:servlet中的Httprequest的doGet和doPost方法
定义:将“请求”封装成对象,以便使用不同的请求。命令模式解决了应用程序中对象的职责以及他们之间的通信方式。
适用场景:请求调用者和请求接收者需要解耦,是的调用者和接收者不直接交互。
优点:
1、降低耦合
2、容易扩展新命令或者一组命令
缺点:命令的无限扩展会增加类的数量,提高系统实现复杂度
开源框架:JDK中的Runnable接口,实现了此接口的都是命令。
定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露改对象的内部表示。
适用场景:
1、访问一个集合对象的内容而无需暴露它的内部表示
2、为遍历不同的集合结构提供一个统一的接口
优点:分离了集合对象的遍历行为
缺点:类的个数成对增加
开源框架:JDK的Iterator
定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖着(观察者)都会受到通知并更新
适用场景:关联行为场景,建立一套触发机制
优点:
1、观察者和被观察者之间建立了一个抽象的耦合
2、观察者模式只是广播通信
缺点:
1、观察者之间有过多的细节依赖,提高时间消耗及程序复杂度
2、使用要得当,要避免循环调用
开源框架:JDK的Event、监听器
定义:定义一个封装一组对象如何交互的对象。通过使对象明确地相互引用来促进松散耦合,并允许独立地改变他们的交互。
适用场景:
1、系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
2、交互的公共行为,如果需要改变行为则可以增加新的中介类
优点:
1、将一对多转化成了一对一,降低程序复杂度
2、类之间解耦
缺点:中介者过多,导致系统复杂
定义:保存一个对象的某个状态,以便在是当的时候恢复对象
适用场景:
1、保存及恢复数据相关业务场景
2、后悔药的时候,即想恢复到之前的状态
优点:
1、为用户提供一种可恢复机制
2、存档信息的封装
缺点:资源占用
开源框架:在spring的webFlow工作流中有用到
定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。为解释一种语言,而为语言创建的解释器。
适用场景:某个特定类型问题发生频率足够高
优点:语法由很多类表示,容易改变及扩展此“语言”
缺点:当语法规则太多时,增加了系统复杂度
开源框架:spring的SpelExpressionParser
定义:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
适用场景:
1、系统有很多类,而他们的区别仅仅在于他们的行为不同
2、一个系统需要动态地在几种算法中选择一种
优点:
1、符合开闭原则
2、避免使用多重条件转移语句
3、提高算法的保密性和安全性
缺点:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2、产生很多策略类
开源框架:JDK的Comparator
定义:允许一个对象在其内部状态改变时,改变它的行为。
适用场景:一个对象存在多个状态(不同状态下行为不同),且状态可相互转换
优点:
1、将不同的状态隔离
2、把各种状态的转换逻辑,分布到State的子类中,减少相互间依赖
3、增加新的状态非常简单
缺点:
状态多的业务场景导致类数据增加,系统变复杂
定义:封装作用于某数据结构(如List/Set//Map)中的各元素的操作。可以在不改变各元素的类的前提下,定义作用于这些元素的操作。
适用场景:
1、一个数据结构(如List/Set//Map)包含很多类型对象
2、数据结构与数据操作分离
优点:增加新的操作很容易,即增加一个新的访问者
缺点:
1、增加新的数据结构困难
2、具体元素变更比较麻烦
定义:为请求创建一个接受此次请求对象的链
适用场景:一个请求的处理需要多个对象当中的一个或几个协作处理
优点:
1、请求的发送者和接受者(请求的处理)解耦
2、责任链可以动态地组合
缺点:
1、如果责任链太长或者处理时间过长,影响性能
2、责任链有可能过多