一、模板模式
模板模式定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
举例1:去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。
举例2:抽象类中进行一个方法实现(模板),相同的代码就在该方法中实现,而对该方法的不同细节:在抽象类中进行抽象,并在子类中进行不同的实现。
二、策略模式
策略模式定义:将执行逻辑和执行单元分离出来,叫策略模式。
举例:比如从上海去北京,可以选择骑自行车、坐汽车、坐火车、坐飞机,不同的出行方式可以看做不同的策略。去北京可以看做执行单元,出行方式可以看做执行逻辑。
三、模板模式与策略模式的区别
- 模板模式都是由抽象类来定义一个算法,在算法实现的不同步骤上抽象方法由子类继承并提供具体实现,常见的就是不同步骤提供doXXX抽象方法留给子类实现。
- 策略模式则是以接口形式提供抽象接口,由具体实现类提供不同算法。
1、策略模式和模板模式有一个最重要的区别,即模板模式一般只针对一套算法,注重对同一个算法的不同细节进行抽象提供不同的实现。而策略模式注重多套算法多套实现,算法和算法只间一般不会有冗余代码(因为不同算法中间的实现一般不同)。
2、策略模式的关注点更广,模板模式的关注点更深,而且两种模式可以一起使用(如java中的抽象类与接口)
总结
模式 | 优点 | 缺点 |
---|---|---|
策略模式 | 灵活性高--->横向扩展性好 | 客户端需要知道全部策略,若策略过多会导致复杂度升高 |
模板模式 | 避免代码冗余--->可维护性好--->纵向扩展性好 | 耦合性较高,子类无法影响父类公用模块代码 |
四、观察者模式--订阅/发布模式
4.1 手写观察者模式
(1)接口定义规范
package comfuping3.base;
/**
* 主题
*/
public interface Subject {
public abstract void addObserver(Observer observer);
public abstract void removeObserver(Observer observer);
public abstract void notify(String msg);
}
package comfuping3.base;
/**
* 观察者
*/
public interface Observer {
public abstract void printMsg(String msg);
}
(2)主题实现类
package comfuping3.impl;
import comfuping3.base.Observer;
import comfuping3.base.Subject;
import java.util.ArrayList;
public class SubjectImpl implements Subject {
private ArrayList<Observer> list=new ArrayList<Observer>();
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notify(String msg) {
for(Observer observer:list){
observer.printMsg(msg);
}
}
}
(3)观察者实现类
package comfuping3.impl;
import comfuping3.base.Observer;
public class ObserverImpl implements Observer {
private String name;
public ObserverImpl(String name) {
this.name = name;
}
@Override
public void printMsg(String msg) {
System.out.println(name+"--"+msg);
}
}
(4)测试代码
package comfuping3;
import comfuping3.base.Observer;
import comfuping3.base.Subject;
import comfuping3.impl.ObserverImpl;
import comfuping3.impl.SubjectImpl;
public class Test {
public static void main(String[] args) {
Subject subject=new SubjectImpl();
subject.addObserver(new ObserverImpl("桃子"));
subject.addObserver(new ObserverImpl("苹果"));
subject.addObserver(new ObserverImpl("西瓜"));
subject.notify("msg");
}
}
(5)输出
桃子--msg
苹果--msg
西瓜--msg