23种设计模式 第三部分 关系模式(2)模板方法模式

原创 2016年08月28日 20:50:32


理解

模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。

泡茶和泡咖啡,步骤很相似:


两种饮品其分别的做法如下代码:

public class Coffee 
{ 
    public void PrepareRecipe() 
    { 
        //烧水 
        BoilWater(); 
        //冲咖啡 
        BrewCoffeeGrinds(); 
        //倒入茶杯中 
        PourInCup(); 
        //加入糖和咖啡 
        AddSugarAndMilk(); 
    } 
    public void BoilWater() 
    { 
        Console.WriteLine("烧水"); 
    }

    public void BrewCoffeeGrinds() 
    { 
        Console.WriteLine("冲咖啡"); 
    }

    public void PourInCup() 
    { 
        Console.WriteLine("倒入杯子中"); 
    }

    public void AddSugarAndMilk() 
    { 
        Console.WriteLine("加糖和牛奶"); 
    } 
}

public class Tea 
{ 
    public void PrepareRecipe() 
    { 
        //烧水 
        BoilWater(); 
        //泡茶 
        SteepTeaBag(); 
        //倒入茶杯中 
        PourInCup(); 
        //加入柠檬 
        AddLemon(); 
    } 
    public void BoilWater() 
    { 
        Console.WriteLine("烧水"); 
    }

    public void SteepTeaBag() 
    { 
        Console.WriteLine("泡茶"); 
    }

    public void PourInCup() 
    { 
        Console.WriteLine("倒入杯子中"); 
    }

    public void AddLemon() 
    { 
        Console.WriteLine("加柠檬"); 
    } 
}
烧水和带入杯子的方法显然是重复的,这样就不符合代码复用。 
对比两种做法,都是需要四个步骤,把相同的使用一个基类,不同的部分分别由自己的子类去实现。

冲咖啡和泡茶以及加入咖啡和牛奶都是属于差不多动作相同的。所以可以继续抽象,抽象为“泡”和“加调料”。抽象后的方法大致如此:




得出的也就是我们的模板方法。下面来看看模板方法模式的类图:


实现

public abstract class CoffeeinBeverage1
{
    public  void BoilWater()
    {
        Console.WriteLine("烧水");
    }

    public  void PrepareRecipe()
    {
        BoilWater();
        Brew();
        PourInCup();
        AddCondiments();
    }

    public  void PourInCup()
    {
        Console.WriteLine("倒入杯子中");
    }

    public abstract void Brew();

    public abstract void AddCondiments();

}
咖啡:

public class Coffee1 : CoffeeinBeverage1
{
    public override void Brew()
    {
        Console.WriteLine("冲咖啡");
        
    }

    public override void AddCondiments()
    {
        Console.WriteLine("加糖和牛奶");
    }
茶:

public class Tea1 : CoffeeinBeverage1
{
    public override void Brew()
    {
        Console.WriteLine("泡茶");
    }

    public override void AddCondiments()
    {
        Console.WriteLine("加柠檬");
    }

}

分析

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法似的自雷可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

这个模式用来创建一个算法的模板。什么是模板?如你所见,模板就是一个方法。更具体的说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。

模板方法挂钩(使用钩子)

在上面的茶水和咖啡中,现在是看起来能喝了,但是有个问题就是有些人喝咖啡喜欢不加任何调味料的。那么我们硬是给客人加,肯定是会生气的。为了满足这个要求,设计模式提供的有这个解决方案——使用钩子。具体什么是钩子,我们小的时间的课本上有个猴子捞月亮的图片:


钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子可以让子类幼儿管理对算法的不同点进行挂钩(子类决定是否覆盖抽象类中的方法)。

public  void PrepareRecipe()
    {
        BoilWater();
        Brew();
        PourInCup();
        //有个判断方法来添加调料
        if (WantCondiments())
        {
            AddCondiments();
        }
    }
    /// <summary>
    /// 加入一个方法,用来判断是否需要加调料
    /// </summary>
    /// <returns></returns>
    public virtual bool WantCondiments()
    {
        return true;
    }


在子类中,可以通过不同的方式类覆盖WantCondiment()方法。用来表示是否要加调料的标准,在此方法中注意必须加入virtual关键字,以便子类中使用override重写。下面看看咖啡中的方法:

public override bool WantCondiments()
   {
       return false;
   }

咖啡:

class Program
  {
      static void Main(string[] args)
      {
          CoffeeinBeverage1 coffeninBeverage = new Coffee1();
          coffeninBeverage.PrepareRecipe();
          Console.ReadKey();
      }
  }

输出:


已经去掉了调料。

模板方法模式还涉及到一个好莱坞原则:

别调用(打电话给)我们,我们会调用(打电话给)你。

在模板方法模式中扮演好莱坞的角色是抽象类,子类是演员的角色。

我们允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些低层组件。换句话说,高层组件对待低层组件的方式是“别调用我们,我们会调用你。”我们要做的事,避免让高层和低层组件之间有明显的环状依赖。

总结

对比模板方法模式、策略模式以及工厂方法模式:

模板方法  - -> 封装可互换的行为,然后使用委托来决定要采用哪一个行为。

策略   -- >子类决定如何实现算法中的步骤。

工厂方法  -- > 由子类决定实例化哪个具体类。



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java开发中的23种设计模式详解----模板方法模式(Template Method)

解释一下模板方法模式,就是指:一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用,先看个关系图:...

java_23种设计模式之模板方法模式

我们看一下模板方法模式的定义:一个操作中算法的骨架,而将这些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 具体适应情况如下: 例如在学开车过程中,我...

23种设计模式之模板方法模式

在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是,某些步骤的具体实现是未知的,或者说某些步骤的实现是会随着环境的变化而变化的。 模板方法...

23种设计模式12---模板方法模式

模板模式业务需求:汽车厂造悍马假设我们是一个汽车公司,现在有客户来了,要求我们造悍马! 既然上级下来命令那就造呗,但是造悍马你得告诉我们汽车有什么功能啊,客户说了:“能启动车,能停止车,能响,能跑。”...

23种设计模式之——模板方法模式

1. 定义 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Temp...

23种设计模式(14)-模板方法模式

模板方法模式     一、概述     二、结构     三、具体案例     四、优缺点和设计思想  一、概述 模板方法模式是类的行为模式。准备一个抽象类...

23种设计模式 第三部分 关系模式(1)策略模式

理解 策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可...

23种设计模式 第三部分 关系模式(4)迭代子模式

理解 迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象...

23种设计模式 第三部分 关系模式(5)责任链模式

理解  责任链模式(Chain of Responsibility),有多个对象,每个对象持有下一个对象的引用,则可以形成一条链,请求在这条链上传递,直到某个对象决定处理该请求。但是发出请求者并不知...

23种设计模式4--行为型模式(策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)

总体来说设计模式分为三大类:     创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。     结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)