1.要点
如果要创建“一系列相关或相互依赖的对象”,而且这个对象的“系列”是易变的,就可以用抽象工厂模式。
抽象工厂模式的结构:
2.DEMO
想开一家餐馆,专卖“鸡鸭鱼系列”,要开餐馆,先得考虑大厨,这个大厨必须得会做“鸡、鸭、鱼”,但做成什么风味的呢?一时没考虑清楚,以后再说吧。先把对大厨的要求列出来
展开
折叠 using System; namespace AbstractFactory { public abstract class Cook //大厨,因为不知道要会做什么风味菜品的厨师,所以这是个抽象的大厨,是个大厨的职位 { //这个大厨必须会做鸡、鸭、鱼 public abstract Chicken CookChicken(); public abstract Duck CookDuck(); public abstract Fish CookFish(); } public abstract class Chicken //未知风味的鸡 { } public abstract class Duck //未知风味的鸭 { } public abstract class Fish //未知风味的鱼 { } }
不管有没有请到大厨,先把餐馆开起来吧,以后请到了大厨,说“做菜”,他就可以做出他拿手风味的“鸡、鸭、鱼”了。
展开
折叠 using System; namespace AbstractFactory { public class Restaurant { public Cook Cook { get; set; } //这是个大厨的职位,因为现在没有厨师,以后真正请到了再派吧 public void Cooking() //到时只要说“做菜”,这个大厨就可以做鸡鸭鱼了 { Cook.CookChicken(); Cook.CookDuck(); Cook.CookFish(); } } }
先请了个川菜的大厨。
展开
折叠 using System; namespace AbstractFactory { public class SichuanCook:Cook //川菜大厨 { public override Chicken CookChicken() { return new SichuanChicken(); //川菜大厨出锅的当然是“四川风味的鸡”了 } public override Duck CookDuck() { return new SichuanDuck(); } public override Fish CookFish() { return new SichuanFish(); } } public class SichuanChicken : Chicken { public SichuanChicken() { Console.WriteLine("这是麻辣鸡"); } } public class SichuanDuck : Duck { public SichuanDuck() { Console.WriteLine("这是麻辣鸭"); } } public class SichuanFish : Fish { public SichuanFish() { Console.WriteLine("这是麻辣鱼"); } } }
请到了大厨,餐馆正式开张
展开
折叠 using System; namespace AbstractFactory { class Program { static void Main(string[] args) { Restaurant restaurant = new Restaurant(); Cook sichuanCook = new SichuanCook(); //请到一位精通川菜的师傅 restaurant.Cook = sichuanCook; //让这位师傅当大厨 restaurant.Cooking(); //做菜 } } }
运行:
看来餐馆运行正常。
开餐馆时没想到这地方人喜欢吃上海菜,川菜生意不太好,所以打算改做上海菜,现在有两种选择:一种是让这川菜师傅改做上海菜,但这太麻烦,得让他学(要修改川菜大厨类和川菜风味的鸡鸭鱼);另一种是直接请个会做上海菜的师傅当大厨。当然第二种方案简单了。
展开
折叠 using System; namespace AbstractFactory { public class ShanghaiCook:Cook //会做上海菜的师傅 { public override Chicken CookChicken() { return new ShanghaiChicken(); //上海风味的鸡 } public override Duck CookDuck() { return new ShanghaiDuck(); } public override Fish CookFish() { return new ShanghaiFish(); } } public class ShanghaiChicken:Chicken { public ShanghaiChicken() { Console.WriteLine("这是红烧鸡"); } } public class ShanghaiDuck:Duck { public ShanghaiDuck() { Console.WriteLine("这是红烧鸭"); } } public class ShanghaiFish:Fish { public ShanghaiFish() { Console.WriteLine("这是红烧鱼"); } } }
把餐馆大厨重新换一下
展开
折叠 using System; namespace AbstractFactory { class Program { static void Main(string[] args) { Restaurant restaurant = new Restaurant(); Cook shanghaiCook = new ShanghaiCook(); //另请一位上海菜师傅 restaurant.Cook = shanghaiCook; //让这位师傅当大厨 restaurant.Cooking(); //做菜 } } }
完全不用对餐馆做任何更改,就可以做出上海风味了,当然想要其它的风味也是很简单了。
将以上各个文件单独编译交给客户使用,如果客户提出要做其它风味的,只用增加个大厨的DLL交给客户,客户就可以在Main方法中指定做出另一种风味了。