New
这是一个典型的情况, 我们需要在运行时来实例化一些具体的类. 在需要修改或者扩展的时候我们就需要改这段代码. 一个程序中可能会多次出现类似的代码, 这使得维护和更新非常困难而且容易出错.
通过面向接口的编程, 我们可以把自己从各种变化中隔离出来, 因为如果代码是面向接口的话, 那么通过多态机制, 任何实现了该接口的新类都可以直接被使用.
所以别忘了设计原则: 对修改关闭.
需求
假设你是个披萨店老板, 有以下代码:
这是订购披萨的过程.
而你可能需要多种披萨:
这里就是根据参数来创建不同类型的披萨实例. 然后再进行下一步操作.
但是这样的事情可能会发生: 添加新类型披萨, 淘汰某些类型的披萨.
对代码修修改改. 所以这不是对修改关闭. 上面那部分代码需要修修改改, 下面那部分代码是固定不变的. 那最好的办法就是封装它.
封装对象的创建
需要把变化的部分封装起来, 也就是把创建披萨那部分代码移动到另外一个对象里, 而这个对象将专注于创建披萨.
针对这种对象, 它有一个名字, 叫工厂(Factory). 工厂会处理对象创建的细节.
建立一个简单的披萨工厂
这个类只有一个任务: 为客户创建披萨.
为什么不适用静态(static)方法?
可以使用static方法, 这样的话你就不需要创建一个对象然后再调用方法了. 但是这么做也有一个缺点, 那就是不可以对它继承了, 也无法改变create方法的行为了.
使用SimpleFactory之后:
简单工厂 Simple Factory
简单工厂实际上并不是设计模式, 可以更多的认为是一种编程范式. 但是使用的却是非常广泛.
理清一下目前的情况:
C#实现:
namespace C04FactoryPattern.Bases
{
public interface IPizza
{
string Type { get; }
void Prepare();
void Bake();
void Cut();
void Box();
}
}
namespace C04FactoryPattern.Bases
{
public interface IPizzaStore
{
Pizza OrderPizza(string type);
}
}
namespace C04FactoryPattern.Bases
{
public abstract class Pizza: IPizza
{
public abstract string Type { get;}
public void Prepare()
{
Console.WriteLine($"{Type} is Preparing...");
}
public void Bake()
{
Console.WriteLine($"{Type} is Baking...");
}
public void Cut()
{
Console.WriteLine($"{Type} is Cutting...");
}
public void Box()
{
Console.WriteLine($"{Type} is Boxing...");
}
}
}
namespace C04FactoryPattern.Models
{
public class CheesePizza : Pizza
{
public override string Type => nameof(CheesePizza);
}
public class ClamPizza : Pizza
{
public override string Type => nameof(ClamPizza);
}
public class PepperoniPizza : Pizza
{
public override string Type => nameof(PepperoniPizza);
}
public class VeggiePizza : Pizza
{
public override string Type => nameof(VeggiePizza);
}
}
namespace C04FactoryPattern.SimpleFactory
{
public class SimplePizzaFactory
{
public Pizza CreatePizza(string type)
{
Pizza pizza = null;
switch (type)
{
case nameof(CheesePizza):
pizza = new CheesePizza();
break;
case nameof(ClamPizza):
pizza = new ClamPizza();
break;
case nameof(PepperoniPizza):
pizza = new PepperoniPizza();
break;
case nameof(VeggiePizza):
pizza = new VeggiePizza();
break;
}
return pizza;
}
}
}
namespace C04FactoryPattern.SimpleFactory
{
public class PizzaStore: IPizzaStore
{
private readonly SimplePizzaFactory _factory;
public PizzaStore(SimplePizzaFactory factory)
{
_factory = factory;
}
public Pizza OrderPizza(string type)
{
var pizza = _factory.CreatePizza(type);
if (pizza != null)
{
pizza.Prepare();
pizza.Bake();
pizza.Cut();
pizza.Box();
Console.WriteLine($"{type} Done!!!");
}
else
{
Console.WriteLine("We don't have this kind of pizza!!");
}
return pizza;
}
}
}
测试:
namespace C04FactoryPattern
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Simple Factory:");
PizzaStore pizzaStore = new PizzaStore(new SimplePizzaFactory());
pizzaStore.OrderPizza(nameof(CheesePizza));
pizzaStore.OrderPizza(nameof(PepperoniPizza));
Console.ReadLine();
}
}
}
下面是我的关于ASP.NET Core Web API相关技术的公众号--草根专栏: