一周两个设计模式—设计模式之模板模式(第七周)

118 阅读3分钟

背景:

昨天作为嘉宾参加了第一届小学生编程大赛,最终的结果力排众议让那个使用策略模式的小孩获得了第一名(那个小孩是红孩儿),这不 又获得了牛魔王的谢意,今天还在睡梦中和玉兔约会呢,他们的感情更近了一部,拉拉小手、亲亲小嘴已经没什么问题了,结果做到一半 电话又响了,出乎意料居然是牛郎打来的,细听之下原来是牛郎进入了咖啡馆工作,最近正在维护、升级之前的系统,现在正在升级整个 接单流程,从订单接收到订单结束的流程,结果整理之下整个人都混乱了,整个系统是在订单发起开始、统一的接收订单,但是具体接单 人不同、不同的人制作咖啡的手法也不同、然后统一的发送订单、最后统一结束订单,他已经完成了,但是感觉有点怪怪的,于是来请教 这个一代目了。

牛郎的代码:

interface order{

      interface sendOrder()

      interface receiveOrder()

      interface doCoffee()

      interface issue()

      interface endOrder()

}

然后具体实现了这些方法,有修改的时候和新增的时候也是很方便的,但是又有一种说不上来的怪异,感觉还有改进的空间,小犬一时也 没感觉怪异,于是开始仔细查看代码,终于找到问题了,这个里面sendOrder()、issue()、endOrder()调用的方法都是一样的,只是 接单人和接单人制作咖啡的手法不同,是否可以自动实现统一发单、结束订单和结束整体业务的实现呢?并且通过请教主人之后有了以下 的代码:

abstract class TemplatePattern {

    final fun template() {
        this.sendOrder()
        this.receiveOrder()
        this.doCoffee()
        this.issue()
        this.endOrder()
    }

    private fun sendOrder() {
        Log.v("======", "发送订单")
    }

    abstract fun receiveOrder()

    abstract fun doCoffee()

    private fun issue() {
        Log.v("======", "送出订单")
    }

    private fun endOrder() {
        Log.v("======", "结束订单")
    }

}

把接口改为了抽象类,这不是重点,重点是以下方法,

  final fun template() {
        this.sendOrder()
        this.receiveOrder()
        this.doCoffee()
        this.issue()
        this.endOrder()
    }

这个就是整体的流程,其中共同的三个方法已经在抽象类中进行了实现,这样只要具体实现接单人员和具体的制作方法就可以了,并且顺 序执行就可以了,这就是模板模式。

具体实现:

class TemplateManager(var name:String):TemplatePattern() {
    override fun receiveOrder() {
        Log.v("========","$name 接收了订单")
        Thread.sleep(1000)
    }

    override fun doCoffee() {
        Log.v("========","$name 制作了咖啡")
        Thread.sleep(1000)
    }
}

  var tem = TemplateManager("哪吒")
  tem.template()

定义:

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特
定步骤 

优点:

它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继
续扩展。

它在父类中提取了公共的部分代码,便于代码复用。

部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

缺点:

对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。

父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。

总结:

模板模式就像模具一样,按照既定的步骤一步步的实现,当然其中可以有部分定制的步骤依赖于具体实现,但是不能完全定制,那样
模板模式就失去了意义。