三种工厂模式
三种工厂模式
简单工厂实现#
简单工厂模式(严格来说这不算一种Gof的设计模式,更像是一种编程习惯)属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有相同的父类,应用继承将决定工厂的生产什么产品的决定权直接交到了客户手中,然后客户在输入自己的需求,得到最终的结果。
运用简单工厂模式实现生产pizza的业务场景。
/// <summary>
/// pizza创建工厂
/// </summary>
public class PizzaFactory
{
public static Pizza CreatePizza(string pizzaType)
{
switch (pizzaType)
{
case "Cheese":
return new CheesePizza();
case "ApplePie":
return new ApplePiePizza();
default:
return new SomeOtherPizza();
}
}
}
public abstract class Pizza
{
public string Name { get; set; }
public void Prepare()
{
Console.WriteLine($"Preparing {Name}");
}
public void Cut()
{
Console.WriteLine($"Cutting the {Name}");
}
public void Bake()
{
Console.WriteLine($"Baking the {Name}");
}
public void Box()
{
Console.WriteLine($"Boxing the {Name}");
}
}
public class ApplePiePizza : Pizza
{
public ApplePiePizza()
{
Name = "ApplePie";
}
}
public class CheesePizza : Pizza
{
public CheesePizza()
{
Name = "Cheese";
}
}
public class SomeOtherPizza : Pizza
{
public SomeOtherPizza()
{
Name = "Other";
}
}
//调用
class Program
{
static void Main(string[] args)
{
Pizza pizza = PizzaFactory.CreatePizza("cheese");
pizza.Box();
}
}
//输出:
//Preparing Cheese
//Cutting the Cheese
//Baking the Cheese
//Boxing the Cheese
简单工厂模式实现了生成Pizza类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成Pizza的逻辑代码,但是,简单工厂并不符合“开放-封闭”原则(对扩展开放,对修改关闭),如果要加一种类型VeggiePizza,你就要修改工厂类里面的生成产品的代码,在这里你就要增加Swich-Case。对于这个问题,我们的工厂方法模式就可以解决这个问题。
工厂模式#
运用工厂模式实现生产pizza的业务场景。
/// <summary>
/// 工厂接口
/// </summary>
interface IFactory
{
Pizza CreatePizza();
}
/// <summary>
/// CheesePizza工厂方法
/// </summary>
public class CheesePizzaFactory : IFactory
{
public Pizza CreatePizza()
{
return new CheesePizza();
}
}
/// <summary>
/// ApplePiePizza工厂方法
/// </summary>
public class ApplePiePizzaFactory : IFactory
{
public Pizza CreatePizza()
{
return new ApplePiePizza();
}
}
class Program
{
static void Main(string[] args)
{
IFactory factory = new CheesePizzaFactory();
Pizza cheesePizza = factory.CreatePizza();
cheesePizza.Prepare();
cheesePizza.Cut();
cheesePizza.Bake();
cheesePizza.Box();
//输出:
//Preparing Cheese
//Cutting the Cheese
//Baking the Cheese
//Boxing the Cheese
}
}
工厂模式中我们通过对应的工厂类来生成对应的Pizza,在这里符合“开闭”原则,无论加多少Pizza类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品Pizza类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同类型的Pizza会在不同的地区会有不同的准备方式,以材料(面团Dough,果酱Sauce)的不同而变幻口味等,同地区不同类型的Pizza可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。
抽象工厂模式#
运用工厂模式实现生产pizza的业务场景。
/// <summary>
/// 面团
/// </summary>
public interface Dough
{
void Dough();
}
/// <summary>
/// 纽约面团
/// </summary>
public class NYDough : Dough
{
public void Dough()
{
Console.WriteLine("NYDough");
}
}
/// <summary>
/// 芝加哥面团
/// </summary>
public class ChicagoDough : Dough
{
public void Dough()
{
Console.WriteLine("ChicagoDough");
}
}
/// <summary>
/// 果酱
/// </summary>
public interface Sauce
{
void Sauce();
}
/// <summary>
/// 纽约果酱
/// </summary>
public class NYSauce : Sauce
{
public void Sauce()
{
Console.WriteLine("NYSauce");
}
}
/// <summary>
/// 芝加哥果酱
/// </summary>
public class ChicagoSauce : Sauce
{
public void Sauce()
{
Console.WriteLine("ChicagoSauce");
}
}
/// <summary>
/// 建造披萨原料工厂 接口
/// </summary>
public interface IPizzaIngredientFactory
{
Dough CreateDough();
Sauce CreateSauce();
}
/// <summary>
/// 纽约披萨工厂
/// </summary>
public class NYPizzaIngredientFactory : IPizzaIngredientFactory
{
public Dough CreateDough()
{
return new NYDough();
}
public Sauce CreateSauce()
{
return new NYSauce();
}
}
/// <summary>
/// 芝加哥披萨工厂
/// </summary>
public class ChicagoPizzaIngredientFactory : IPizzaIngredientFactory
{
public Dough CreateDough()
{
return new ChicagoDough();
}
public Sauce CreateSauce()
{
return new ChicagoSauce();
}
}
public abstract class Pizza
{
public string Name { get; set; }
/// <summary>
/// 面团
/// </summary>
public Dough Dough { get; set; }
/// <summary>
/// 酱汁
/// </summary>
public Sauce Sauce { get; set; }
public abstract void Prepare();
public void Cut()
{
Console.WriteLine($"Cutting the {Name}");
}
public void Bake()
{
Console.WriteLine($"Baking the {Name}");
}
public void Box()
{
Console.WriteLine($"Boxing the {Name}");
}
}
public class ApplePiePizza : Pizza
{
IPizzaIngredientFactory _pizzaIngredientFactory;
public ApplePiePizza(IPizzaIngredientFactory pizzaIngredient)
{
this._pizzaIngredientFactory = pizzaIngredient;
Name = "ApplePie";
}
public override void Prepare()
{
Console.WriteLine($"Preparing { Name}");
Dough = _pizzaIngredientFactory.CreateDough();
Dough.Dough();
Sauce = _pizzaIngredientFactory.CreateSauce();
Sauce.Sauce();
}
}
public