`

模板模式

 
阅读更多
what

定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中。
使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

why

(1) 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。

(2) 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为,它鼓励我们恰当使用继承来实现代码复用。

(3) 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。

(4) 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则。

how

public abstract class HummerModel {
/*
* 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正
* 是要能够发动起来,那这个实现要在实现类里了
*/
protected abstract void start();
//能发动,还要能停下来,那才是真本事
protected abstract void stop();
//喇叭会出声音,是滴滴叫,还是哔哔叫
protected abstract void alarm();
//引擎会轰隆隆的响,不响那是假的
protected abstract void engineBoom();
//那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑
final public void run() {
//先发动汽车
this.start();
//引擎开始轰鸣
this.engineBoom();
//要让它叫的就是就叫,喇嘛不想让它响就不响
if(this.isAlarm()){
this.alarm();
}
//到达目的地就停车
this.stop();
}
//钩子方法,默认喇叭是会响的
protected boolean isAlarm(){
return true;
}
}


public class HummerH1Model extends HummerModel {
private boolean alarmFlag = true; //要响喇叭
protected void alarm() {
System.out.println("悍马H1鸣笛...");
}
protected void engineBoom() {
System.out.println("悍马H1引擎声音是这样的...");
}
protected void start() {
System.out.println("悍马H1发动...");
}
protected void stop() {
System.out.println("悍马H1停车...");
}
protected boolean isAlarm() {
return this.alarmFlag;
}
//要不要响喇叭,是由客户来决定的
public void setAlarm(boolean isAlarm){
this.alarmFlag = isAlarm;
}
}

public class HummerH2Model extends HummerModel {
protected void alarm() {
System.out.println("悍马H2鸣笛...");
}
protected void engineBoom() {
System.out.println("悍马H2引擎声音是这样的...");
}
protected void start() {
System.out.println("悍马H2发动...");
}
protected void stop() {
System.out.println("悍马H2停车...");
}
//默认没有喇叭的
protected boolean isAlarm() {
return false;
}
}


缺点

需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象,此时,可结合桥接模式来进行设计。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics