深入浅出设计模式之模板方法模式

引子

我们发现茶喝咖啡有相似的地方,当然,泡茶喝和泡咖啡也有相似的地方。

咖啡和茶的类:
//咖啡类
public class Coffee {
    //准备咖啡
    void prepare(){
        //加入咖啡
        addCoffee();
        //加入水
        boilWater();
        //加牛奶
        addMilk();
    }

    private void addCoffee(){
        System.out.println("add coffee!");
    }

    private void boilWater(){
        System.out.println("boil water!");
    }

    private void addMilk(){
        System.out.println("boil milk!");
    }

}

//茶类
public class Tea {
    //准备茶
    void prepare(){
        addTea();
        boilWater();
        addLemon();
    }

    private void addTea(){
        System.out.println("add tea!");
    }

    private void boilWater(){
        System.out.println("boil water!");
    }

    private void addLemon(){
        System.out.println("boil lemon!");
    }

}

出现重复的代码,两个类都有倒入水方法,我们需要把这些重复代码抽取出来

第一版的实现

public abstract class Beverage {
    //因为prepare在两个类中不一样,所以只能作为抽象方法
    abstract void prepare();

    //两个类中都一样,可以提取出来
    private void boilWater(){
        System.out.println("boil water!");
    }

}

但是我们抽象的不够彻底,另外两个方法虽然不一样,但是方法相似。

比如咖啡的addCoffee 与茶的addTea,咖啡的addMilk 与茶的addLemon,虽然动作不一样,方式行为方式一样,我们可以用一个方法来代替相似的行为。

public abstract class Beverage {
    // 因为prepare在两个类中不一样,所以只能作为抽象方法
    void prepare() {
        //冲泡
        brew();
        // 加入水
        boilWater();
        // 加配料
        addBurden();
    }
    //抽象方法由子类实现
    abstract void brew();

    abstract void addBurden();

    // 两个类中都一样,可以提取出来
    private void boilWater() {
        System.out.println("boil water!");
    }
}

只要子类实现两个抽象的方法就行了。

定义

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

其实我们对这些代码一点都不陌生,因为模板方法可以说是最常用的方法之一。

public abstract class Beverage {
    // 因为prepare在两个类中不一样,所以只能作为抽象方法
    final void prepare() {
        //冲泡
        brew();
        // 加入水
        boilWater();
        // 加配料
        addBurden();
    }
    //抽象方法由子类实现
    abstract void brew();

    abstract void addBurden();

    // 两个类中都一样,可以提取出来
    final void boilWater() {
        System.out.println("boil water!");
    }

    //钩子函数
    void hook(){}
}

我们一般发由子类实现的函数用abstract修饰,已实现的方法final防止子类修改,也可以加入一个普通的钩子函数,子类可以实现,也可以不实现

在Swing中的JFame里的paint就是一个钩子函数,当子类实现paint时,就会运行paint里的函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值