创建型模式:工厂方法

工厂方法模式(Factory Method)

定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

第一版

工厂方法类图

namespace 工厂方法模式01
{
    /// <summary>
    /// 运算抽象类-抽象产品
    /// </summary>
    public abstract class Operation
    {
        /// <summary>
        /// 数字A
        /// </summary>
        public double NumA { get; set; }
        /// <summary>
        /// 数字B
        /// </summary>
        public double NumB { get; set; }

        /// <summary>
        /// 抽象运算方法
        /// </summary>
        /// <returns></returns>
        public abstract double GetResult();
    }
}
namespace 工厂方法模式01
{
    /// <summary>
    /// 加法运算-具体产品
    /// </summary>
    public class Add:Operation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override double GetResult()
        {
            return NumA + NumB;
        }
    }
}
namespace 工厂方法模式01
{
    /// <summary>
    /// 减法-具体产品
    /// </summary>
    public class Sub:Operation
    {
        /// <summary>
        /// 重写抽象方法
        /// </summary>
        /// <returns></returns>
        public override double GetResult()
        {
            return NumA - NumB;
        }
    }
}
namespace 工厂方法模式01
{
    /// <summary>
    /// 乘法-具体产品
    /// </summary>
    public class Mul:Operation
    {
        public override double GetResult()
        {
            return NumA * NumB;
        }
    }
}
namespace 工厂方法模式01
{
    /// <summary>
    /// 除法-具体产品
    /// </summary>
    public class Div:Operation
    {
        public override double GetResult()
        {
            return NumA / NumB;
        }
    }
}
namespace 工厂方法模式01
{
    /// <summary>
    /// 运算工厂
    /// </summary>
    public class OperationFactory
    {
        /// <summary>
        /// 工厂方法
        /// </summary>
        /// <param name="operate">运算符</param>
        /// <returns></returns>
        public static Operation CreateOperate(string operate)
        {
            Operation oper;
            switch (operate)
            {
                case "+":
                    oper = new Add();
                    break;
                case"-":
                    oper = new Sub();
                    break;
                case "*":
                    oper = new Mul();
                    break;
                case "/":
                    oper = new Div();
                    break;
            }
            return null;
        }
    }
}
using System;

namespace 工厂方法模式01
{
    class Program
    {
        static void Main(string[] args)
        {
            //简单工厂模式实现
            Console.WriteLine("请输入数字A:");
            string numA = Console.ReadLine();

            Console.WriteLine("请输入数字B");
            string numB = Console.ReadLine();

            Console.WriteLine("请输入运算符号:");
            string strOperation = Console.ReadLine();

            Operation oper = OperationFactory.CreateOperate(strOperation);

            oper.NumA = double.Parse(numA);
            oper.NumB = double.Parse(numB);

            double result = oper.GetResult();

            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}

第二版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 工厂方法模式02
{
    /// <summary>
    /// 抽象运算类-抽象产品
    /// </summary>
    public abstract class Operation
    {
        public double NumA { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public double NumB { get; set; }

        /// <summary>
        /// 运算
        /// </summary>
        /// <returns></returns>
        public abstract double GetResult();
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 加法运算-具体产品
    /// </summary>
    public class Add:Operation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override double GetResult()
        {
            return NumA + NumB;
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 减法-具体产品
    /// </summary>
    public class Sub:Operation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override double GetResult()
        {
            return NumA - NumB;
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 乘法-具体产品
    /// </summary>
    public class Mul:Operation
    {
        public override double GetResult()
        {
            return NumA * NumB;
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 除法-具体产品
    /// </summary>
    public class Div:Operation
    {
        public override double GetResult()
        {
            return NumA / NumB;
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 抽象工厂接口
    /// </summary>
    public interface IFactory
    {
        Operation CreateOperation();
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 加法工厂
    /// </summary>
    public class AddFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new Add();
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 减法工厂
    /// </summary>
    public class SubFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new Sub();
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 乘法工厂
    /// </summary>
    public class MulFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new Mul();
        }
    }
}
namespace 工厂方法模式02
{
    /// <summary>
    /// 除法工厂
    /// </summary>
    public class DivFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new Div();
        }
    }
}
using System;

namespace 工厂方法模式02
{
    class Program
    {
        static void Main(string[] args)
        {
            //工厂方法模式实现
            IFactory factory = new AddFactory();
            Operation oper=factory.CreateOperation();

            oper.NumA = 50;
            oper.NumB = 65;
            double result = oper.GetResult();

            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}

优点

  • 克服了简单工厂违反开放-封闭原则的缺点,又保持了封装对象创建过程集中封装了对象的创建,使得需要更换对象时,不需要大的改动就可以实现。
  • 降低了客户端程序与产品对象的耦合,工厂方法模式是简单工厂的进一步抽象和推广,因为使用了多态性,工厂方法模式保持了简单工厂的优点。

缺点

  • 每增加一个产品,就需要新增一个产品工厂类,增加了额外的开发量。
  • 客户端需要决定实例化哪一个工厂,判断的问题依然存在。工厂方法把简单工厂内部的逻辑判断转移到了客户端代码来进行,如果要添加功能本来时要修改工厂类的现在需要修改客户端。
原文地址:https://www.cnblogs.com/wgx0428/p/12862396.html