Factory Method工厂方法模式

  • 定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类,属于创建型模式
  • 在此模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生产具体的产品对象,使一个类的实例化延迟到其子类,由子类来确定实例化哪个具体的产品类。
    image.png
   [TestClass]
    public class UnitTest2
    {
        [TestMethod]
        public void TestMethod1()
        {
            //测试
            //当前只是实例化了工厂,工厂的产品还尚未实例化
            Creator creator = new ConcreteCreator();
            //调用了“工厂方法”后,产品这个对象才真正被实例化
            var product = creator.FactoryMethod();
        }
    }

    /// <summary>
    /// 产品抽象类 是子类ConcreteProduct的泛华
    /// </summary>
    public abstract class Product
    {

    }

    /// <summary>
    /// 具体的产品 继承自 Product
    /// </summary>
    public class ConcreteProduct : Product
    {

    }

    /// <summary>
    /// 实例化工厂
    /// </summary>
    public abstract class Creator
    {
        /// <summary>
        /// 定义创建产品对象的公共接口
        /// </summary>
        /// <returns></returns>
        public abstract Product FactoryMethod();
    }


    public class ConcreteCreator : Creator
    {
        public override Product FactoryMethod()
        {
            Console.Write("具体对象的方法");
            return new ConcreteProduct();
        }
    }

案例

调用者只需要通过工厂获取想要的对象,而不需要知道对象的创建具体细节,
参考用例,一家工厂可以生产TV,MP4,MP3等电子产品,这些电子产品都有播放功能。

 namespace DesignPatterns.FactoryMethod
{
    public class Factory
    {
        /// <summary>
        /// 通过名称决定实例化哪种子类对象
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <returns></returns>
        public Product GetProduct(string name)
        {
            if (name.ToLower() == "tv")
                return new TV();
            if (name.ToLower() == "mp4")
                return new MP4();
            if (name.ToLower() == "mp3")
                return new MP3();
            throw new Exception("unknow product name");
        }

        public static void Test()
        {
            var factory = new Factory();
            var tv = factory.GetProduct("tv");
            tv.Play();
            var mp4 = factory.GetProduct("mp4");
            mp4.Play();
        }
    }

    public abstract class Product
    {
        public abstract void Play();
    }

    public class TV : Product
    {
        public override void Play()
        {
            Console.WriteLine("TV play");
        }
    }

    public class MP4 : Product
    {
        public override void Play()
        {
            Console.WriteLine("MP4 play");
        }
    }

    public class MP3 : Product
    {
        public override void Play()
        {
            Console.WriteLine("MP3 play");
        }
    }
}

实际运用

在具体的运用场景中比如日志存储方式,有远程TCP,UDP存储,本地磁盘存储,发邮件,这些具体的存储方式,可以通过配置工厂方法中的种类,由调用者选择具体哪种存储方式;
工厂方法只适合统一的对象创建,就是子类和父类拥有相同的构造函数,如果构造函数不一,那么工厂方法将很难管理起这些子类。

查看github源码

posted @ 2019-09-04 16:56  sands  阅读(154)  评论(0编辑  收藏  举报