模块方法模式主要是用在超类与子类之间关系之中。
模块方法模式定义:在一个方法中定义一个算法的骨架,而将以一些方法实现推迟到子类中。模块方法使得子类可以不改变算法结构的情况下,重新定义算法中的某些方法。
具体的说:模板就是一个方法,这个方法将算法定义成一组步骤,其中任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同事由子类提供部分方法实现。
//定义模块方法
public abstract class CoffeeTeaWithHook
{
public string PrepareRecipe()
{
StringBuilder sb = new StringBuilder();
sb.Append(BoilWater());
sb.Append(Brew());
sb.Append(PourWater());
if(CustomerWantsCondiments())
{
sb.Append(AddCondiments());
}
return sb.ToString();
}
public abstract string Brew();
public abstract string AddCondiments();
string BoilWater()
{
return "Boiling Water\n";
}
string PourWater()
{
return "Pouring into cuo\n";
}
public virtual bool CustomerWantsCondiments()//定义一个钩子
{
return true;
}
}
//定义coffee
public class Coffee:CoffeeTeaWithHook
{
public Coffee(){}
public override string Brew()
{
return "Dripping coffee through filter\n";
}
public override string AddCondiments()
{
return "Adding sugar and milk\n";
}
public override bool CustomerWantsCondiments()
{
return false;
}
}
//定义tea
public class Tea:CoffeeTeaWithHook
{
public Tea(){}
public override string Brew()
{
return "Steeping the tea\n";
}
public override string AddCondiments()
{
return "Adding lemon\n ";
}
}
//测试示例
public class CoffeeTeaWithHookTest
{
public static void Main()
{
Tea tea = new Tea();
Console.WriteLine(tea.PrepareRecipe());
Console.WriteLine("coffee使用了钩子,所以他没有添加糖和牛奶");
Coffee coffee = new Coffee();
Console.WriteLine(coffee.PrepareRecipe());
}
}
说明:钩子是一种被声明在抽象类中的方法,但是只有空的或者默认的实现。钩子的存在可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定 。有了钩子能够决定要不要覆盖抽象类的方法。如果子类不提供自己的方法,那么抽象类会提供一个默认的实现
模板方法模式要点:
1.模板方法定义了算法的步骤,把这些步骤的实现推迟到子类
2.模板方法模式为我们提供一种代码复用的重要技巧
3.模板方法的抽象类可以定义具体方法、抽象方法和钩子
4.抽象方法有子类实现
5.钩子是一种方法,他在抽象类中不做事情、或者只做默认的事情,子类可以选择要不要去覆盖它
6.工厂方法是模板方法的一种特殊版本