六、咖啡屋的例子
在前面的咖啡攤項目裡,由於沒有供客人坐的桌子,所有的咖啡均沒有環境的影響。換言之,咖啡僅有內蘊狀態,也就是咖啡的種類,而沒有外蘊狀態。
下面考慮一個規模稍稍大一點的咖啡屋(Coffee Shop)項目。屋子裡有很多的桌子供客人坐,系統除了需要提供咖啡的"風味"之外,還需要跟蹤咖啡被送到哪一個桌位上,因此,咖啡就有了桌子作為外蘊狀態。
由於外蘊狀態的存在,沒有外蘊狀態的單純享元模式不再符合要求。系統的設計可以利用有外蘊狀態的單純享元模式。系統的代碼如下:
using System;
using System.Collections;
public abstract class Order
{
// 將咖啡賣給客人
public abstract void Serve(Table table);
// 返回咖啡的名字
public abstract string GetFlavor();
}
public class Flavor : Order
{
private string flavor;
// 構造函數,內蘊狀態以參數方式傳入
public Flavor(string flavor)
{
this.flavor = flavor;
}
// 返回咖啡的名字
public override string GetFlavor()
{
return this.flavor;
}
// 將咖啡賣給客人
public override void Serve(Table table)
{
Console.WriteLine("Serving table {0} with flavor {1}", table.Number, flavor);
}
}
public class FlavorFactory
{
private Hashtable flavors = new Hashtable();
public Order GetOrder(string key)
{
if(! flavors.ContainsKey(key))
flavors.Add(key, new Flavor(key));
return ((Order)flavors[key]);
}
public int GetTotalFlavorsMade()
{
return flavors.Count;
}
}
public class Table
{
private int number;
public Table(int number)
{
this.number = number;
}
public int Number
{
get { return number; }
}
}
public class ClIEnt
{
private static FlavorFactory flavorFactory;
private static int ordersMade = 0;
public static void Main( string[] args )
{
flavorFactory = new FlavorFactory();
TakeOrder("Black Coffee");
TakeOrder("Capucino");
TakeOrder("Espresso");
TakeOrder("Capucino");
TakeOrder("Espresso");
TakeOrder("Black Coffee");
TakeOrder("Espresso");
TakeOrder("Espresso");
TakeOrder("Black Coffee");
TakeOrder("Capucino");
TakeOrder("Capucino");
TakeOrder("Black Coffee");
Console.WriteLine("\nTotal Orders made: " + ordersMade);
Console.WriteLine("\nTotal Flavor objects made: " +
flavorFactory.GetTotalFlavorsMade());
}
private static void TakeOrder(string aFlavor)
{
Order o = flavorFactory.GetOrder(aFlavor);
// 將咖啡賣給客人
o.Serve(new Table(++ordersMade));
}
}