首页 > 技术文章 > 设计模式--3.模板方法模式

fubaizhaizhuren 2016-07-09 17:19 原文

   

1.模版方法模式
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得一个子类可以不改变一个算法的结构,即可重新定义该算法的某些特定步骤。
模版方法模式使用的java中的继承机制,抽像类叫做抽像模版, 它的方法分为两类
(1) 基本方法:由子类实现的方法,并且在模板方法中被调用
(2)模板方法:可以有一个或几个(即一个框架),实现对基本方法的调用,完成固定的逻辑。
为了防止恶意的操作,一般模板方法都加上final关键字,不允许被重写。

2.在抽象类中,有一个isAlarm方法,模版方法根据其返回值决定是否要响喇叭,该方法影响了模版方法的执行结果,该方法就叫钩子方法(Hook Method)

3.优点
(1)封装不变部分,扩展可变部分
(2)提取公共代码,便于维护
(3)行为由父类控制,子类实现

4.缺点
(1)子类的执行结果影响到父类,影响代码可读性。

5.使用场景
(1)多个子类有公有方法,并且逻辑基本相同
(2)重要、复杂的算法,可以把核心部分设计成模板方法,周边相关功能和细节由子类实现。

 

 

AbstractCar类

public abstract class AbstractCar {
    protected abstract void start();
    protected abstract void stop();
    protected abstract void alarm();
    protected boolean isAlarm(){
        return false;
    }
    
    final public void run(){
        this.start();
        if(this.isAlarm()){
            this.alarm();
        }
        
        this.stop();
    }
}

奥迪类

public class AodiCar extends AbstractCar {

    @Override
    protected void start() {
        System.out.println("aodi start ...");

    }

    @Override
    protected void stop() {
        System.out.println("aodi stop ...");

    }

    @Override
    protected void alarm() {
        System.out.println("aodi alarm ...");
    }

    @Override
    protected boolean isAlarm(){
        return false;
    }
     
}

宝马类

/*
 * isAlarm是一个实现方法。 其作用是模板方法根据其返回值决定是否要响
    喇叭, 子类可以覆写该返回值
 */
public class BaoMaCar extends AbstractCar {
    private boolean alarmFlag = false;

    @Override
    protected void start() {
        System.out.println("baoma car start....");

    }

    @Override
    protected void stop() {
        System.out.println("baoma car stop ...");

    }

    @Override
    protected void alarm() {
        System.out.println("baoma car alarm ...");

    }
    
    protected boolean isAlarm(){
        return this.alarmFlag;
    }
     
    public void setAlarmFlag(boolean flagTmp){
        this.alarmFlag = flagTmp;
    }

}

场景类,Main

public class Main {
    
    public static void main(String[] args) {
        BaoMaCar bm = new BaoMaCar();
        bm.setAlarmFlag(true);
        bm.run();
        
        AodiCar ac = new AodiCar();
        ac.run();
    }
}

 

推荐阅读