模板方法模式介绍
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- AbstractClass (DataObject)
定义抽象的基本操作,具体的子类定义来实现算法的步骤
实现一个定义算法框架的模板方法。 模板方法调用基元操作以及在AbstractClass中定义的操作或其他对象的操作。
- ConcreteClass (CustomerDataObject)
实现基本操作,而不是执行子类特定的步骤的算法
模板方法模式
using UnityEngine;
using System.Collections;
public class TemplateMethodStructure : MonoBehaviour
{
void Start ( )
{
AbstractClass aA = new ConcreteClassA();
aA.TemplateMethod();
AbstractClass aB = new ConcreteClassB();
aB.TemplateMethod();
}
}
/// <summary>
/// The 'AbstractClass' abstract class
/// </summary>
abstract class AbstractClass
{
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
// The "Template method"
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
Debug.Log("");
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
class ConcreteClassA : AbstractClass
{
public override void PrimitiveOperation1()
{
Debug.Log("ConcreteClassA.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Debug.Log("ConcreteClassA.PrimitiveOperation2()");
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
class ConcreteClassB : AbstractClass
{
public override void PrimitiveOperation1()
{
Debug.Log("ConcreteClassB.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Debug.Log("ConcreteClassB.PrimitiveOperation2()");
}
}
模板方法模式案例1
using UnityEngine;
using System.Collections;
/*
用于创建一组必须执行一组类似方法的子类
您创建一个抽象类,其中包含一个称为模板方法的方法
Template方法包含一系列每个subblcass对象都会调用的方法调用
子类对象可以重写一些方法调用
*/
namespace TemplateMethodPatternExample1
{
public class TemplateMethodPatternExample1 : MonoBehaviour
{
void Start()
{
Hoagie cust12Hoagie = new ItalienHoagie();
cust12Hoagie.MakeSandwich();
Hoagie cust13Hoagie = new VeggieHoagie();
cust13Hoagie.MakeSandwich();
}
}
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.");
}
}
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");
}
}
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");
}
}
}
}