zoukankan      html  css  js  c++  java
  • JS设计模式(8)模板方法模式

    什么是模板方法模式?

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

    主要解决:一些方法通用,却在每一个子类都重新写了这一方法。

    何时使用:有一些通用的方法。

    如何解决:将这些通用算法抽象出来。

    应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。

    优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

    缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

    使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

     

    泡茶和泡咖啡

    来对比下泡茶和泡咖啡过程中的异同

    步骤泡茶泡咖啡
    1 烧开水 烧开水
    2 浸泡茶叶 冲泡咖啡
    3 倒入杯子 倒入杯子
    4 加柠檬 加糖

     

     

     

     

     

    可以清晰地看出仅仅在步骤 2 和 4 上有细微的差别,下面着手实现:

    const Drinks = function() {}
    
    Drinks.prototype.firstStep = function() {
      console.log('烧开水')
    }
    
    Drinks.prototype.secondStep = function() {}
    
    Drinks.prototype.thirdStep = function() {
      console.log('倒入杯子')
    }
    
    Drinks.prototype.fourthStep = function() {}
    
    Drinks.prototype.init = function() { // 模板方法模式核心:在父类上定义好执行算法
      this.firstStep()
      this.secondStep()
      this.thirdStep()
      this.fourthStep()
    }
    
    const Tea = function() {}
    
    Tea.prototype = new Drinks
    
    Tea.prototype.secondStep = function() {
      console.log('浸泡茶叶')
    }
    
    Tea.prototype.fourthStep = function() {
      console.log('加柠檬')
    }
    
    const Coffee = function() {}
    
    Coffee.prototype = new Drinks
    
    Coffee.prototype.secondStep = function() {
      console.log('冲泡咖啡')
    }
    
    Coffee.prototype.fourthStep = function() {
      console.log('加糖')
    }
    
    const tea = new Tea()
    tea.init()
    
    // 烧开水
    // 浸泡茶叶
    // 倒入杯子
    // 加柠檬
    
    const coffee = new Coffee()
    coffee.init()
    
    // 烧开水
    // 冲泡咖啡
    // 倒入杯子
    // 加糖

    钩子

    假如客人不想加佐料(糖、柠檬)怎么办,这时可以引人钩子来实现之,实现逻辑如下:

    // ...
    
    Drinks.prototype.ifNeedFlavour = function() { // 加上钩子
      return true
    }
    
    Drinks.prototype.init = function() { // 模板方法模式核心:在父类上定义好执行算法
      this.firstStep()
      this.secondStep()
      this.thirdStep()
      if (this.ifNeedFlavour()) { // 默认是 true,也就是要加调料
        this.fourthStep()
      }
    }
    
    // ...
    const Coffee = function() {}
    
    Coffee.prototype = new Drinks()
    // ...
    
    Coffee.prototype.ifNeedFlavour = function() {
      return window.confirm('是否需要佐料吗?') // 弹框选择是否佐料
    }
  • 相关阅读:
    兔子数
    忠诚
    mysql字段名与关键字冲突(near "to":syntax error)
    C/C++使用心得:enum与int的相互转换
    ubuntu重新安装 apache2
    ubuntu 删除mysql
    Notepad++ 代码格式化
    linux文件字符集转换(utf8-gb2312)
    字符编码详解——彻底理解掌握编码知识,“乱码”不复存在
    c语言判断是否是utf8字符串,计算字符个数
  • 原文地址:https://www.cnblogs.com/wuguanglin/p/TemplatePattern.html
Copyright © 2011-2022 走看看