原型模式(Prototype Pattern)

      原型模式,使我们可以灵活地动态创建拥有某些稳定接口的“易变”对象。原型模式中涉及到了深拷贝(deep copy)的概念,所谓深拷贝就是对使用了引用类型的类对象的完整拷贝,如果拷贝的类中没有用到引用类型,则可以使用object自带的MemberWiseClone()方法实现拷贝。

      下面的例子使用了原型模式实现匹萨店的原料生成,结构图与实现代码中的对应关系如下

      IngredientManager = Client

      Dough(Sauce/Cheese/Clams) = Prototype

      ThickCrustDough(PlumTomatoSauce/MozzarellaCheese/FrozenClams) = ConcretePrototype1

      ThinCrustDough(MarinaraSauce/ReggianoCheese/FreshClams) = ConcretePrototype2

 

 

    class App
    {
        
static void Main()
        {
            
//在纽约的一家匹萨店,一位客人订购了一份干酪匹萨
            PizzaStore nyStore = new NYPizzaStore();

            Pizza nyPizza 
= nyStore.CreatePizza(PizzaType.干酪匹萨);

            Console.ReadLine();
        }
    }
    
#region 匹萨快餐店
    
public abstract class PizzaStore
    {
        
public abstract Pizza CreatePizza(PizzaType type);
    }

    
/// <summary>
    
/// 纽约匹萨店
    
/// </summary>
    public class NYPizzaStore : PizzaStore
    {
        
public override Pizza CreatePizza(PizzaType type)
        {
            Pizza pizza 
= null;
            
            
switch (type)
            {
                
case PizzaType.干酪匹萨:
                    pizza 
= new CheesePizza(new ThinCrustDough(), new MarinaraSauce(), new ReggianoCheese(), new FreshClams());
                    pizza.Name 
= "纽约式干酪匹萨";
                    
break;
                
case PizzaType.蛤蜊匹萨:
                    pizza 
= new ClamPizza(new ThinCrustDough(), new MarinaraSauce(), new ReggianoCheese(), new FreshClams());
                    pizza.Name 
= "纽约式蛤蜊匹萨";
                    
break;
                
default:
                    
break;
            }

            
if (pizza != null) pizza.Produce();

            
return pizza;
        }
    }

    
/// <summary>
    
/// 芝加哥匹萨店
    
/// </summary>
    public class ChicagoPizzaStore : PizzaStore
    {
        
public override Pizza CreatePizza(PizzaType type)
        {
            Pizza pizza 
= null;
            
            
switch (type)
            {
                
case PizzaType.干酪匹萨:
                    pizza 
= new CheesePizza(new ThickCrustDough(), new PlumTomatoSauce(), new MozzarellaCheese(), new FrozenClams()); 
                    pizza.Name 
= "芝加哥式干酪匹萨";
                    
break;
                
case PizzaType.蛤蜊匹萨:
                    pizza 
= new ClamPizza(new ThickCrustDough(), new PlumTomatoSauce(), new MozzarellaCheese(), new FrozenClams());
                    pizza.Name 
= "芝加哥式蛤蜊匹萨";
                    
break;
                
default:
                    
break;
            }

            
if (pizza != null) pizza.Produce();

            
return pizza;
        }
    }
    
#endregion

    
#region 匹萨
    
public enum PizzaType
    {
        干酪匹萨 
= 1,
        蛤蜊匹萨 
= 2
    }

    
public abstract class Pizza
    {
        
protected PizzaIngredient ingredient;

        
protected abstract void Prepare();

        
protected virtual void Bake()
        {
            Console.WriteLine(
"350度烘烤25分钟");
        }

        
protected virtual void Cut()
        {
            Console.WriteLine(
"将匹萨切成尖角型");
        }

        
protected virtual void Box()
        {
            Console.WriteLine(
"将匹萨打包成商务餐装");
        }

        
public virtual void Produce()
        {
            Prepare();
            Bake();
            Cut();
            Box();
        }

        
public string Name { getset; }
    }

    
public class CheesePizza : Pizza
    {
        Dough dough;
        Sauce sauce;
        Cheese cheese;
        Clams clams;

        
public CheesePizza(Dough dough, Sauce sauce, Cheese cheese, Clams clams)
        {
            
this.dough = dough;
            
this.sauce = sauce;
            
this.cheese = cheese;
            
this.clams = clams;
        }

        
protected override void Prepare()
        {
            
this.ingredient = IngredientManager.Construct(dough, sauce, cheese, clams);

            Console.WriteLine(
"准备做一个 {0}", Name);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.DoughIngredient[0].PizzaDough(), ingredient.DoughIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.SauceIngredient[0].PizzaSauce(), ingredient.SauceIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.CheeseIngredient[0].PizzaTopCheese(), ingredient.CheeseIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.ClamsIngredient[0].PizzaTopClams(), ingredient.ClamsIngredient.Count);
        }
    }

    
public class ClamPizza : Pizza
    {
        Dough dough;
        Sauce sauce;
        Cheese cheese;
        Clams clams;

        
public ClamPizza(Dough dough, Sauce sauce, Cheese cheese, Clams clams)
        {
            
this.dough = dough;
            
this.sauce = sauce;
            
this.cheese = cheese;
            
this.clams = clams;
        }

        
protected override void Prepare()
        {
            
this.ingredient = IngredientManager.Construct(dough, sauce, cheese, clams);

            Console.WriteLine(
"准备做一个 {0}", Name);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.DoughIngredient[0].PizzaDough(), ingredient.DoughIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.SauceIngredient[0].PizzaSauce(), ingredient.SauceIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.CheeseIngredient[0].PizzaTopCheese(), ingredient.CheeseIngredient.Count);
            Console.WriteLine(
"     准备{0}{1}份", ingredient.ClamsIngredient[0].PizzaTopClams(), ingredient.ClamsIngredient.Count);
        }
    }
    
#endregion

    
#region 匹萨原料

    
public class IngredientManager
    {
        
public static PizzaIngredient Construct(Dough dough, Sauce sauce, Cheese cheese, Clams clams)
        {
            PizzaIngredient ingredient 
= new PizzaIngredient();
            ingredient.DoughIngredient.Add(dough.Clone(
true));
            ingredient.DoughIngredient.Add(dough.Clone(
true));
            ingredient.DoughIngredient.Add(dough.Clone(
true));

            ingredient.SauceIngredient.Add(sauce.Clone(
true));
            ingredient.SauceIngredient.Add(sauce.Clone(
true));

            ingredient.CheeseIngredient.Add(cheese.Clone(
true));
            ingredient.ClamsIngredient.Add(clams.Clone(
true));

            
return ingredient;
        }
    }

    
public class PizzaIngredient
    {
        
private List<Dough> dough = new List<Dough>();
        
public List<Dough> DoughIngredient
        {
            
get { return dough; }
            
set { dough = value; }
        }

        
private List<Sauce> sauce = new List<Sauce>();
        
public List<Sauce> SauceIngredient
        {
            
get { return sauce; }
            
set { sauce = value; }
        }

        
private List<Cheese> cheese = new List<Cheese>();
        
public List<Cheese> CheeseIngredient
        {
            
get { return cheese; }
            
set { cheese = value; }
        }

        
private List<Clams> clams = new List<Clams>();
        
public List<Clams> ClamsIngredient
        {
            
get { return clams; }
            
set { clams = value; }
        }
    }

    
#endregion

    
#region 匹萨使用的原料

    
public interface Dough
    {
        
string PizzaDough();
        Dough Clone(
bool deep);
    }

    [Serializable]
    
public class ThickCrustDough : Dough
    {
        
public string PizzaDough()
        {
            
return "厚皮面团";
        }

        
public Dough Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Dough;
            }
            
else
            {
                
return this.MemberwiseClone() as Dough;
            }
        }
    }
    [Serializable]
    
public class ThinCrustDough : Dough
    {
        
public string PizzaDough()
        {
            
return "薄皮面团";
        }

        
public Dough Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Dough;
            }
            
else
            {
                
return this.MemberwiseClone() as Dough;
            }
        }
    }

    
public interface Sauce
    {
        
string PizzaSauce();
        Sauce Clone(
bool deep);
    }

    [Serializable]
    
public class PlumTomatoSauce : Sauce
    {
        
public string PizzaSauce()
        {
            
return "番茄沙司";
        }

        
public Sauce Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Sauce;
            }
            
else
            {
                
return this.MemberwiseClone() as Sauce;
            }
        }
    }

    [Serializable]
    
public class MarinaraSauce : Sauce
    {
        
public string PizzaSauce()
        {
            
return "意式沙司";
        }

        
public Sauce Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Sauce;
            }
            
else
            {
                
return this.MemberwiseClone() as Sauce;
            }
        }
    }

    
public interface Cheese
    {
        
string PizzaTopCheese();

        Cheese Clone(
bool deep);
    }

    [Serializable]
    
public class MozzarellaCheese : Cheese
    {
        
public string PizzaTopCheese()
        {
            
return "意式奶酪";
        }

        
public Cheese Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Cheese;
            }
            
else
            {
                
return this.MemberwiseClone() as Cheese;
            }
        }
    }

    [Serializable]
    
public class ReggianoCheese : Cheese
    {
        
public string PizzaTopCheese()
        {
            
return "乳酪奶酪";
        }

        
public Cheese Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Cheese;
            }
            
else
            {
                
return this.MemberwiseClone() as Cheese;
            }
        }
    }

    
public interface Clams
    {
        
string PizzaTopClams();
        Clams Clone(
bool deep);
    }

    [Serializable]
    
public class FrozenClams : Clams
    {
        
public string PizzaTopClams()
        {
            
return "冰冻蛤蜊";
        }

        
public Clams Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Clams;
            }
            
else
            {
                
return this.MemberwiseClone() as Clams;
            }
        }
    }

    [Serializable]
    
public class FreshClams : Clams
    {
        
public string PizzaTopClams()
        {
            
return "生鲜蛤蜊";
        }

        
public Clams Clone(bool deep)
        {
            
if (deep)
            {
                
return Utility.DeepCopy(thisas Clams;
            }
            
else
            {
                
return this.MemberwiseClone() as Clams;
            }
        }
    }
    
#endregion

    
public class Utility
    {
        
public static object DeepCopy(object obj)
        {
            MemoryStream stream 
= new MemoryStream();
            BinaryFormatter formatter 
= new BinaryFormatter();
            formatter.Serialize(stream, obj);
            stream.Position 
= 0;
            
            
return formatter.Deserialize(stream);
        }
    }

 

posted @ 2009-07-17 23:01  binfen  阅读(286)  评论(0编辑  收藏  举报