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方法中指定做出另一种风味了。