天天看点

设计模式系列14---管流程不管细节的模板方法模式编码实现类图后记

写了这么久,花的时间最多的是在选故事,找图上,写一篇能看的文章真的不容易啊。

设计模式系列14---管流程不管细节的模板方法模式编码实现类图后记

今天来介绍一款“高端智能”的机器人—炒菜机器侠。

一个可以会帮我们炒菜的机器人,懒人必备,价格不要你的2999,不要1999,只要899!

心动了嘛?赶紧拿起手头的手机,扫码购买吧!

我们的炒菜机器人,只要你给他材料,就可以煮出你想要的菜。

什么扬州炒饭,潮州炒饭都不是问题!

好了,上面是一个引入的介绍,我们来看下实际的内容。

既然有了这么个厉害的机器人,我们来看下他的炒菜流程。

  1. 洗锅
  2. 加食用油
  3. 加食材炒
  4. 出锅

这样一款 高度智能的炒菜机器人,他的流程我们简化成上面的步骤。

接着我们尝试编码实现他

编码实现

首先我们根据上面的流程,写一个我们抽象出来的记起厨师

public abstract class RobotCook {

    protected abstract void clean();

    protected abstract void addOil();

    protected abstract boolean isNeedOil();

    protected abstract void addFoodAndCook();

    protected abstract void done();

    public final void start() {
        clean();
        if (isNeedOil()) {
            addOil();
        }
        addFoodAndCook();
        done();
    }

}
           

我们的机器厨师的流程如上,我们可以看到的是,这里有一个东西是叫

isNeedOil()

的函数来告诉我们,这个菜要不要加油,有不用加油的菜?有的。这个函数是我们的钩子函数,很有用的,后面再做介绍。

这个是我们抽象出来的机器人,我们来看下实际的机器人。

public class ConcreteCook extends RobotCook {

    @Override
    protected void clean() {
        System.out.println("清洗");
    }

    @Override
    protected void addOil() {
        System.out.println("加花生油");
    }

    @Override
    protected boolean isNeedOil() {
        return true;
    }

    @Override
    protected void addFoodAndCook() {
        System.out.println("开始炒菜");
    }

    @Override
    protected void done() {
        System.out.println("主人,菜好了,来拿走吧!");
    }
}
           

我们的机器人现在实现了我们的所有的机器人的基本逻辑功能,现在我们来测试下能不能运行炒菜。

public class Client {

    public static void main(String[] args) {
        ConcreteCook cook = new ConcreteCook();
        cook.start();
    }
}
           

好了,我们的自动高智能的煮菜机器人就这么写好了。

菜也煮出来了,不过有个问题啊,那个好像我们的是否要加油没弄好啊。

返回的都是

false

,不加油,这菜很难吃啊。我们需要让给用户配置下这菜要不要加油啊,加多少油等等啊!这才叫对用户友好吗!

所以我们改一改这个机器,变成下面这样

public class ConcreteCook extends RobotCook {

    boolean isAddOil;

    public void setAddOil(boolean addOil) {
        isAddOil = addOil;
    }

    @Override
    protected void clean() {
        System.out.println("cleaning");
    }

    @Override
    protected void addOil() {
        System.out.println("加花生油");
    }

    @Override
    protected boolean isNeedOil() {
        return isAddOil;
    }

    @Override
    protected void addFoodAndCook() {
        System.out.println("开始炒菜");
    }

    @Override
    protected void done() {
        System.out.println("主人,菜好了,来拿走吧!");
    }
}
           

我们加多了一个属性

isAddOil

,通过这个的设置才觉得是否要加油

public class Client {

    public static void main(String[] args) {
        ConcreteCook cook = new ConcreteCook();
        cook.setAddOil(true);
        cook.start();
    }
}
           

这样我们的机器就更对用户友好啦!

在这个知与不知的过程,我们的模版方法模型就写完了!

你可能还没发觉到,不过没关系,这里我们开始解释下。

我们的机器的start方法是一个

final

型的,因为内部的流程已经规定好了,不允许修改。

而对于我们具体实现的的方法,都是使用

protected

,因为我们的用户不需要知道这部分内容。他只要知道调用我们的

final

型的

start

方法就可以了

另外就是我们的那个

isNeedOil

这个方法,他影响着我们的流程是否需要加油,对这类方法,我们称他做

钩子方法(Hook Methongd)

,提供一定的定制。

类图

设计模式系列14---管流程不管细节的模板方法模式编码实现类图后记

这个就是我们的uml图啦

所谓的模板方法模式就是在模板方法中按照一个的规则和顺序调用基本方法,我们上面那个例子就是

Start()

方法按照规定的顺序调用本类的其他方法,并且由

isNeedOil

方法的返回值确定 start中的执行顺序变更,

后记

写完这个只控制流程,对各个方法的具体实现不过控制的模板方法后,剩下的设计模式就剩下九个啦,按照现在的速度,下周内可以搞定,在写好了,再去回顾前面写的内容,再做改进。接着就可以开始看下写点源码探索系列的中篇了,最近想的是除了看安卓系统部分的源码,应该也得加点第三方库的。

曾经看了像

EventBus

Volley

等知名库的代码,也写过点文章记录过。

感觉应该可以把中篇加点这样的内容。

不知不觉又是凌晨时刻,写得有点带感了,不过还是挺累的,而且写作能力还有待加强啊!

继续阅读