天天看点

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

New

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory
设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

这是一个典型的情况, 我们需要在运行时来实例化一些具体的类. 在需要修改或者扩展的时候我们就需要改这段代码. 一个程序中可能会多次出现类似的代码, 这使得维护和更新非常困难而且容易出错.

通过面向接口的编程, 我们可以把自己从各种变化中隔离出来, 因为如果代码是面向接口的话, 那么通过多态机制, 任何实现了该接口的新类都可以直接被使用.

所以别忘了设计原则: 对修改关闭.

需求

假设你是个披萨店老板, 有以下代码:

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

这是订购披萨的过程.

而你可能需要多种披萨:

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

这里就是根据参数来创建不同类型的披萨实例. 然后再进行下一步操作.

但是这样的事情可能会发生: 添加新类型披萨, 淘汰某些类型的披萨.

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

对代码修修改改. 所以这不是对修改关闭. 上面那部分代码需要修修改改, 下面那部分代码是固定不变的. 那最好的办法就是封装它.

封装对象的创建

需要把变化的部分封装起来, 也就是把创建披萨那部分代码移动到另外一个对象里, 而这个对象将专注于创建披萨. 

针对这种对象, 它有一个名字, 叫工厂(Factory). 工厂会处理对象创建的细节.

建立一个简单的披萨工厂

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

这个类只有一个任务: 为客户创建披萨.

为什么不适用静态(static)方法?

可以使用static方法, 这样的话你就不需要创建一个对象然后再调用方法了. 但是这么做也有一个缺点, 那就是不可以对它继承了, 也无法改变create方法的行为了.

使用SimpleFactory之后:

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

简单工厂 Simple Factory

简单工厂实际上并不是设计模式, 可以更多的认为是一种编程范式. 但是使用的却是非常广泛.

理清一下目前的情况:

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 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();
        }
    }
}      
设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

下面是我的关于ASP.NET Core Web API相关技术的公众号--草根专栏:

设计模式学习(四): 1.简单工厂 (附C#实现)New需求建立一个简单的披萨工厂简单工厂 Simple Factory

继续阅读