五、一個咖啡攤的例子
在這個咖啡攤(Coffee Stall)所使用的系統裡,有一系列的咖啡"風味(Flavor)"。客人到攤位上購買咖啡,所有的咖啡均放在台子上,客人自己拿到咖啡後就離開攤位。咖啡有內蘊狀態,也就是咖啡的風味;咖啡沒有環境因素,也就是說沒有外蘊狀態。如果系統為每一杯咖啡都創建一個獨立的對象的話,那麼就需要創建出很多的細小對象來。這樣就不如把咖啡按照種類(即"風味")劃分,每一種風味的咖啡只創建一個對象,並實行共享。
使用咖啡攤主的語言來講,所有的咖啡都可按"風味"劃分成如Capucino、Espresso等,每一種風味的咖啡不論賣出多少杯,都是全同、不可分辨的。所謂共享,就是咖啡風味的共享,制造方法的共享等。因此,享元模式對咖啡攤來說,就意味著不需要為每一份單獨調制。攤主可以在需要時,一次性地調制出足夠一天出售的某一種風味的咖啡。
很顯然,這裡適合使用單純享元模式。系統的設計如下:
using System;
using System.Collections;
public abstract class Order
{
// 將咖啡賣給客人
public abstract void Serve();
// 返回咖啡的名字
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()
{
Console.WriteLine("Serving flavor " + 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 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();
ordersMade++;
}
}