设计模式-工厂模式

简单工厂模式,https://www.cnblogs.com/Kyle-Wang/p/16063512.html

一、工厂模式的引出

  工厂模式是简单工厂模式的升级版本。简单工厂一般就是提供一个CreateInstance方法,允许通过传入一个对象类型的参数,来实例化返回一个对象给调用方。这样违背了设计模式6大原则种的“单一职责”。

因为CreateInstance方法里面,耦合了一组对象。它既可以实例化A对象,也可以实例化B、C、D对象,职责不单一会导致,假设以后需要新增一个对象E,就i必须修改CreateInstance方法。而我们一般需要遵守“开闭原则”

  开闭原则:对扩展开放(open) - 对修改关闭(closed) ,在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)的基础上,能扩展其功能(扩展开放)。

  因此,引出工厂模式。

二、工厂模式的实现

  1、新增工厂接口

    public interface IFactory
    {
        IRace CreateInstance();
    }

  

  2、新增具体工厂,实现工厂接口

public class HumanFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Human();
            return race;
        }
    }

public class NEFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new NE();
            return race;
        }
    }

public class ORCFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new ORC();
            return race;
        }
    }

  

  3、调用方式

IFactory humanFactory = new HumanFactory();
IRace human = humanFactory.CreateInstance();

IFactory neFactory = new NEFactory();
IRace ne = neFactory.CreateInstance();

  这样的话,如果要新增一个Undead种族,只需要新增一个UndeadFactory就行了

public class UndeadFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Undead();
            return race;
        }
    }

 

三、工厂模式的意义

  在引出简单工厂模式之前,有一个最开始的代码

  

Player player = new Player()
{
     Id = 123,
     Name = "Eleven"
};
Human race = new Human();//1 最原始最习惯的
player.PlayHuman(race);
ORC oRC = new ORC();
player.PlayORC(oRC);

  现在工厂模式的调用方式似乎又回到了原点,甚至还要繁琐点。最开始是依赖了具体种族对象,需要什么种族就new哪个种族,

  而现在,变成了需要哪个种族,new哪个种族的工厂,然后再由工厂创建对象。这样有什么意义呢?

  1、目前所举例的种族,实例化时都很简单,但如果种族的实例化是很复杂的呢?比如新种族Six

public class Six : IRace
    {
        public Six(string name, int id, object special, IRace race1, IRace race2, IRace race3)
        {

        }

        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name);
        }
    }

  该种族实例化时,需要传递多个参数。此时工厂模式就体现出优势了,调用者不需要关心Six种族需要什么参数,他要做的只需要通过SixFactory来获取Six。

  而最开始的代码,调用者必须知道Six种族的所需参数才能正确使用。

public class SixFactory : IFactory
    {
        public virtual IRace CreateInstance()
        {
            IRace race = new Six("Yoyo", 123, new Undead(), new Undead(), new Human(), new NE());//一些具体业务
            return race;
        }
    }

 

  2、留下了扩展点,上面的SixFactory工厂的CreateInstance方法定义为virtual虚方法,允许子类重写,这在很多框架里面,都时基本用法。允许自定义工厂类继承框架自带的工厂类,重写对象实例化方法。

/// <summary>
    /// 我们扩展的工厂
    /// </summary>
    public class SixFactoryExtend : SixFactory
    {
        public override IRace CreateInstance()
        {
            Console.WriteLine("这里是我们扩展的工厂");

            return base.CreateInstance();
        }
    }

   调用方式

IFactory sixFactory = new SixFactoryExtend();

 

posted @ 2022-04-03 14:27  暗,伏!  阅读(29)  评论(0编辑  收藏  举报