设计模式01: 简单工厂模式

问题引入

实现一个简单的计算器:输入数字和加减乘除操作符,输出结果

按照单纯的面向过程方法,可能有以下实现:

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Num1: ");
                double num1 = Convert.ToDouble(Console.ReadLine());

                Console.WriteLine("Num2: ");
                double num2 = Convert.ToDouble(Console.ReadLine());

                Console.WriteLine("Oper: ");
                string strOper = Console.ReadLine();

                double res = 0d;

                switch(strOper)
                {
                    ///
                }


            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Press any key to quit...");
            Console.ReadKey();
        }
    }

以上代码暂时可以满足需求,但是如果现在需要增加一个case: 求模运算,那此时便需要修改switch中的代码了,这不符合对修改封闭,对扩展开放的原则。此时可以考虑简单工厂模式:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Num1: ");
            double num1 = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Num2: ");
            double num2 = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Oper: ");
            string strOper = Console.ReadLine();

            double res = 0d;

            Operation oper = OperationFactory.createOperate(strOper);
            oper.Num1 = num1;
            oper.Num2 = num2;

            Console.WriteLine(Convert.ToString(oper.GetResult()));


        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }

        Console.WriteLine("Press any key to quit...");
        Console.ReadKey();
    }
}

abstract class Operation
{
    private double _num1;
    private double _num2;

    public double Num1
    {
        get { return _num1; }
        set { _num1 = value; }
    }

    public double Num2
    {
        get { return _num2; }
        set { _num2 = value; }
    }

    public abstract double GetResult();

}

class OperationAdd : Operation
{
    public override double GetResult()
    {
        return Num1 + Num2;
    }
}

class OperationSub : Operation
{
    public override double GetResult()
    {
        return Num1 - Num2;
    }
}

class OperationMul : Operation
{
    public override double GetResult()
    {
        return Num1 * Num2;
    }
}

class OperationDiv : Operation
{
    public override double GetResult()
    {
        if (Num2 == 0)
            throw new Exception("Divisor can not be zero!!!");
        return Num1 / Num2;
    }
}

class OperationFactory
{
    public static Operation createOperate(string type)
    {
        Operation oper = null;
        switch (type)
        {
            case "+":
                oper = new OperationAdd();
                break;
            case "-":
                oper = new OperationSub();
                break;
            case "*":
                oper = new OperationMul();
                break;
            case "/":
                oper = new OperationDiv();
                break;
        }
        return oper;
    }
}

在上述模式中,我们首先抽象出一个Operation抽象类,统一了GetResult操作,然后不同的运算操作都继承自这个抽象类,并根据不同的运算自己实现GetResult。接着使用一个OperationFactory实现了switch的功能,这样客户端只需要把运算的类型传进去即可。
当我们需要增加一种运算的时候,需要做两步:

  1. 定义一个新的类继承自Operation,实现GetResult接口
  2. OperationFactoryswitch语句中增加一个对应的分支

显然,使用了简单工厂模式,我们还是避免不了修改switch里面的代码,不过相比之前代码,有以下优点:

  1. 封装了switch,客户端不需要自己判断
  2. 将不同的算法分离,新增加一个算法只需要实现父类所要求的接口,原来的算法不会被暴露出来,减少被误改的风险

缺点也是有的:

  1. 若是要频繁增加算法,需要不断修改简单工厂里的判断分支
  2. 客户端使用时需要知道两个类:OperationOperationFactory

你可能感兴趣的:(设计模式01: 简单工厂模式)