模版方法模式

模版方法模式

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

案例

我们拿做饭的例子来说明。比如就做个西红柿鸡蛋吧。我们可以简单地定义一下步骤:

  • 第一步:放油

  • 第二步:放鸡蛋

有两个厨师,好厨师和坏厨师,虽然好厨师和坏厨师的手法大不相同,但是执行顺序都是一样的,都是先放油再放鸡蛋。

uml

代码

/**
 * Cooker模版
 */
public abstract class Cooker {

    public abstract void egg();

    public abstract void oil();

    /**
     * 注意这里用final修饰
     * 子类不能重写
     */
    final public void cook() {
        oil();
        egg();
        System.out.println("大公告成");
    }
}

public class GoodCooker extends Cooker {
    @Override
    public void egg() {
        System.out.println("放入适量鸡蛋");
    }

    @Override
    public void oil() {
        System.out.println("放入适量油");
    }
}

优缺点

优点:

(1)把不可改变的封装起来,把能够改变的扩展开来

(2)他把很多类的共同操作给封装了起来,利于维护

(3)其实我们发现,我们在定义行为时候都是由父类去定义,然后子类去实现即可。

缺点:

缺点很简单,我们发现虽然我们把一些类的共同操作封装了起来,但是当这些类比较多时,效果就不好了,因为有一个拓展子类都需要继承它,子类多了就不好了。

钩子函数

钩子就是给子类一个授权,让子类来决定模板方法的逻辑执行。就比如在炒西红柿鸡蛋的时候,由子类去决定是否要加调料。我们去实现一下:

/**
 * Cooker模版
 */
public abstract class Cooker {

    public abstract void egg();

    public abstract void oil();

    public boolean addSalt() {
        return false;
    }

    /**
     * 注意这里用final修饰
     * 子类不能重写
     */
    final public void cook() {
        oil();
        egg();
        if (addSalt()) {
            System.out.println("放入盐");
        } else
            System.out.println("不放入盐");
        System.out.println("大公告成");
    }
}

子类就可以设置其逻辑是否执行。

posted @ 2020-09-18 17:21  刃牙  阅读(106)  评论(0编辑  收藏  举报