设计模式(8)the Template Method Pattern (模板方法模式)

概念

Template Method(模板方法):

例如做咖啡和茶是有类似的过程的:

  1. 烧水
  2. 混合(放入咖啡或者茶叶)
  3. 倒入杯子
  4. 添加一些附加材料(糖或者其他)

其中步骤2和4有些许不同。我们在写这样的一个类,如果分开写,1,4步骤的代码要被重复写两次。所以可以使用模板模式,写一个咖啡和茶的父类,然后他们都继承这些方法。

实现

// 代码源于Head First Design Pattern 283页
// 咖啡因类饮料的父类。咖啡和茶都可以继承

public abstract class CaffeineBeverage{
    
    //准备
    //使用final是防止子类重写该方法。
    final void prepareRecipe(){
        boilWater(); 
        brew(); //步骤2,混合
        porurInCup();
        addCondiments(); //步骤4,添加
    }
    // 把步骤2.4声明为抽象方法,让子类去实现
    abstract void brew();
    abstract void addCondiments();
    
    
    //相同的方法
    void bolidWater(){
        System.out.println("Boiling water")
    }
    void pourInCup(){
        System.out.println("Pouring into cup")
    }
    
}


//子类:Tea
public class Tea extends CaffeineBeverage{
    
    // 重写抽象方法
    public void brew(){
        System.out.println("Stepping the tea");
    }
    
    public void addCondiments(){
        System.out.println("Adding Lemon")
    }
}



// 子类: Coffee
// 同Tea

比较

使用Template Method

  • 能够最大程度对代码进行重用。

  • 不变的方法集中在父类中,修改起来简单。

  • 提供了其他相类似的子类的接入。只需要实现响应的抽象方法就可以了。

Template Method Method Pattern:

在一个方法里定义一个算法的骨架,其中一些步骤的实现推迟到具体的子类中。模板方法让子类在不改变算法的整体结构情况下,重新定义某些步骤。

Hook(钩子)方法

子类可以重新父类中的hook方法,这些方法能够可能能够改变父类中算法的运行

例如

public abstract class CaffeineBeverage{
    
    //准备
    //使用final是防止子类重写该方法。
    final void prepareRecipe(){
        boilWater(); 
        brew(); //步骤2,混合
        porurInCup();
        // HOOK方法的一种使用
        if(customerWantsCondiments()){
        addCondiments(); //步骤4,添加    
        }
    }
    // 把步骤2.4声明为抽象方法,让子类去实现
    abstract void brew();
    abstract void addCondiments();
    
    
    //相同的方法
    void bolidWater(){
        System.out.println("Boiling water")
    }
    void pourInCup(){
        System.out.println("Pouring into cup")
    }
    
    // hook method,如果子类重写,可以改变prepareRecipe的运行轨迹。
    bool customerWantsCondiments(){
        return true;
    }
}

子类可以通过重写customerWantsCondiments()方法类决定第四步是否添加东西。

可见:

  • 抽象的方法子类是必须实现的
  • hook方法不一定需要子类重写,是一个可选项。

hook方法的用途:

  • 提供给子类去修改算法的可选部分。如上个例子中第四步是可选项。
  • 给子类一个机会去对模板方法中刚刚发生或者即将发生的做出反应,例如向屏幕打印运行信息。

Hollywood Principle

不要调用我们,我们将调用你。

在类设计中,高阶组件调用低阶组件,这个低阶组件有调用了某个高阶组件,然后有调用了一些其他的等,这就产生了依赖腐败。

遵循Hollywood设计原则,让低阶组件把他们自己挂在到系统中,高阶组件决定他们什么时候被需要,如何被使用。换句话说,高阶组件告诉低阶组件:不要调用我们,我将调用你

在我们设计模板方法模式时,父类就告诉子类,不要调用我,我将调用你。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值