设计模式系列14---管流程不管细节的模板方法模式

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

enter image description here
今天来介绍一款“高端智能”的机器人—炒菜机器侠。
一个可以会帮我们炒菜的机器人,懒人必备,价格不要你的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),提供一定的定制。

类图

enter image description here
这个就是我们的uml图啦

所谓的模板方法模式就是在模板方法中按照一个的规则和顺序调用基本方法,我们上面那个例子就是 Start() 方法按照规定的顺序调用本类的其他方法,并且由 isNeedOil 方法的返回值确定 start中的执行顺序变更,

后记

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值