Unity实现设计模式——模板方法模式
模板模式(Template Pattern), 指在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
简单说, 模板方法模式定义一个操作中的算法的骨架,而将这些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
注意模板方法模式和策略模式的区别
模板模式注意强调了抽象类公开定义了一个执行的模板方法,而策略模式是对单个算法的封装更具有独立性
下面使用两个例子去介绍模板方法模式:
1.第一个例子(使用比较抽象的例子)
(一)AbstractClass
abstract class AbstractClass
{
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
// The "Template method"
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
Debug.Log("");
}
}
(二)ConcreteClassA
class ConcreteClassA : AbstractClass
{
public override void PrimitiveOperation1()
{
Debug.Log("ConcreteClassA.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Debug.Log("ConcreteClassA.PrimitiveOperation2()");
}
}
(三)ConcreteClassB
class ConcreteClassB : AbstractClass
{
public override void PrimitiveOperation1()
{
Debug.Log("ConcreteClassB.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Debug.Log("ConcreteClassB.PrimitiveOperation2()");
}
}
(四)测试
public class TemplateMethodStructure : MonoBehaviour
{
void Start ( )
{
AbstractClass aA = new ConcreteClassA();
aA.TemplateMethod();
AbstractClass aB = new ConcreteClassB();
aB.TemplateMethod();
}
}
2.第二个例子(使用一个三明治的制作过程来介绍)
(一)Hoagie 三明治抽象基类
public abstract class Hoagie
{
public void MakeSandwich()
{
Debug.Log("Making new Sandwich");
CutBun();
if (CustomerWantsMeat())
{
AddMeat();
}
if (CustomerWantsCheese())
{
AddCheese();
}
if (CustomerWantsVegetables())
{
AddVegetables();
}
if (CustomerWantsCondiments())
{
AddCondiments();
}
WrapTheHoagie();
}
protected abstract void AddMeat();
protected abstract void AddCheese();
protected abstract void AddVegetables();
protected abstract void AddCondiments();
protected virtual bool CustomerWantsMeat() { return true; } // << called Hook
protected virtual bool CustomerWantsCheese() { return true; }
protected virtual bool CustomerWantsVegetables() { return true; }
protected virtual bool CustomerWantsCondiments() { return true; }
protected void CutBun()
{
Debug.Log("Bun is Cut");
}
protected void WrapTheHoagie()
{
Debug.Log("Hoagie is wrapped.");
}
}
(二)ItalienHoagie 法式三明治
public class ItalienHoagie : Hoagie
{
protected override void AddMeat()
{
Debug.Log("Adding the Meat: Salami");
}
protected override void AddCheese()
{
Debug.Log("Adding the Cheese: Provolone");
}
protected override void AddVegetables()
{
Debug.Log("Adding the Vegetables: Tomatoes");
}
protected override void AddCondiments()
{
Debug.Log("Adding the Condiments: Vinegar");
}
}
(三)VeggieHoagie 素菜三明治
public class VeggieHoagie : Hoagie
{
protected override void AddMeat()
{
}
protected override void AddCheese()
{
}
protected override void AddVegetables()
{
Debug.Log("Adding the Vegetables: Tomatoes");
}
protected override void AddCondiments()
{
Debug.Log("Adding the Condiments: Vinegar");
}
protected override bool CustomerWantsMeat() { return false; }
protected override bool CustomerWantsCheese() { return false; }
}
(四)错误的方式
namespace BadExample
{
// this way you would have to rewrite a lot of code
// especially if something changes or another class differs and does e.g. not AddMeat()
public class ItalienHoagie
{
public void MakeSandwich()
{
CutBun();
AddMeat();
AddCheese();
AddVegtables();
AddCondiments();
WrapHoagie();
}
public void CutBun()
{
Debug.Log("Hoagie is Cut");
}
public void AddMeat()
{
Debug.Log("Added Meat");
}
public void AddCheese()
{
Debug.Log("Added Cheese");
}
public void AddVegtables()
{
Debug.Log("Added Vegies");
}
public void AddCondiments()
{
Debug.Log("Added Condiments");
}
public void WrapHoagie()
{
Debug.Log("Wrapped Hoagie");
}
}
}
(五)测试
public class TemplateMethodPatternExample1 : MonoBehaviour
{
void Start()
{
Hoagie cust12Hoagie = new ItalienHoagie();
cust12Hoagie.MakeSandwich();
Hoagie cust13Hoagie = new VeggieHoagie();
cust13Hoagie.MakeSandwich();
}
}