定义
提供一个建立一系列相关或互相依赖物件的介面,而无需指定它们具体的类别。
主要思想
- 多个类似子类继承父类,通过工厂类进行判断、控制哪个子类负责产出,通过子类调用产出该子类的父类。最后再客户端访问父类就是我们想要的结果了
代码实现
-
项目基本设计
-
创建工厂,以及工厂产出物
创建抽象工厂
/// <summary>
/// 餐厅工厂抽象
/// </summary>
public abstract class CookFactory
{
public abstract Meal Cook();
}
创建工厂产物
/// <summary>
/// 工厂产出抽象
/// </summary>
public abstract class Meal
{
/// <summary>
/// 价格
/// </summary>
public int Price { get; private set; }
/// <summary>
/// 规格
/// </summary>
public string Size { get; set; }
public Meal(int price,string size)
{
this.Price = price;
this.Size = size;
}
/// <summary>
/// 共同拥有吃这个动作
/// </summary>
public abstract void Eat();
}
- 构建实例工厂以及产物
/// <summary>
/// 土豆青椒工厂
/// </summary>
public class PotatoCookFactory : CookFactory
{
public override Meal Cook()
{
return new PotatoPepperMeal(15, "大份");
}
}
/// <summary>
/// 实现青椒土豆产物
/// </summary>
public class PotatoPepperMeal : Meal
{
public PotatoPepperMeal(int price, string size) : base(price, size)
{
Console.WriteLine($"服务员端来了一份{this.Price}的{this.Size}土豆青椒");
}
public override void Eat()
{
Console.WriteLine($"你吃掉了这份{this.Price}元的{this.Size}土豆青椒");
}
/// <summary>
/// 青椒土豆独有的退菜动作
/// 不隶属于抽象产物
/// </summary>
public void ReturnMeal()
{
Console.WriteLine($"你退掉了这份{this.Price}元的{this.Size}土豆青椒");
}
}
在类似实现牛排和番茄炒蛋工厂以及产物
- 实现控制工厂
public interface IFactory:IDisposable
{
CookFactory GetFactory(string name);
}
public class Factory : Disposable, IFactory
{
public CookFactory GetFactory(string name)
{
switch (name)
{
case "番茄炒蛋":
Console.WriteLine("你点了一份番茄炒蛋");
return new TomatoCookFactory();
case "土豆青椒":
Console.WriteLine("你点了一份土豆青椒");
return new PotatoCookFactory();
case "牛排":
Console.WriteLine("你点了一份牛排");
return new SteakCookFactory();
default:
return null;
}
}
}
- 调用
// 实例控制工厂
IFactory factory = new Factory.Factory();
// 生成工厂
var steakFactory = factory.GetFactory("牛排");
var tomatoFactory = factory.GetFactory("番茄炒蛋");
var potatoFactory = factory.GetFactory("土豆青椒");
// 工厂生产
var tomato = tomatoFactory.Cook();
var potato = potatoFactory.Cook();
var steak = steakFactory.Cook();
// 产出物调用方法
steak.Eat();
tomato.Eat();
// 因为产出的Meal这个抽象产出物
// 所以是没办法直接调用土豆青椒独有的退菜动作
// 只能通过反射调用成员类方法或属性实现
// DoMethod是调动动态类中方法的扩展
potato.DoMethod("ReturnMeal");
优点与缺点
优点:工厂模式会控制资源的统一产出,并且能很好的控制程序内同一类型产物的一致性。并且隔离了客户端与底层产出,客户端只需要使用不需要管理底层产出逻辑。并且工厂模式能很好的扩展新产品的产出,例如项目中的菜品,添加新的菜品只需要实现抽象工厂与产物就可实现新的产品产出搭建。
缺点:工厂模式固定了,产物的类型、属性、动作,一旦实现“新产品”这种变动会导致所有继承子类的变动