简单工厂模式

1.简介

  简单工厂模式就是将类的实例化都放在一个工厂类中,用这个类来解耦上层代码

  这样的好处比如:当某个类的名字修改了,只需修改工厂类中对应的这个类的名字就可以了

  我们模拟魔兽争霸游戏来简单介绍一下

  首先,我们建一个接口,用来定义种族动作

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

namespace SimpleFactory
{
    public interface IRace//接口最好就使用public
    {
        void ShowKing();
    }
}

  新建四个类,继承这个接口,表示四个种族

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

namespace SimpleFactory
{
    class Human : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("这里是人类的国王");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    class NE : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("这里是精灵族的国王");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    class Orc : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("这里是兽族的国王");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    class Undead : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("这里是不死族的国王");
        }
    }
}

  新建一个工厂类,用来实现实例化,把类的实例化从上层代码(这里是Program)转移到这个工厂类中

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

namespace SimpleFactory
{
    public class Factory
    {
        public static IRace GetRace(FactoryType factoryType)
        {
            switch(factoryType)
            {
                case FactoryType.Human:return new Human();
                case FactoryType.NE: return new NE();
                case FactoryType.Orc: return new Orc();
                case FactoryType.Undead: return new Undead();
                default:throw new Exception();
            }
        }
    }
    public enum FactoryType
    {
        Human, NE, Orc, Undead
    }
}

  Program代码如下:

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

namespace SimpleFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            IRace race1 = Factory.GetRace(FactoryType.Human);
            race1.ShowKing();

            IRace race2 = Factory.GetRace(FactoryType.NE);
            race2.ShowKing();

            IRace race3 = Factory.GetRace(FactoryType.Orc);
            race3.ShowKing();

            IRace race4 = Factory.GetRace(FactoryType.Undead);
            race4.ShowKing();

            Console.Read();
        }
    }
}

  这样,我们就实现了一个简单工厂模式,把Program从细节代码变成抽象代码

  若Human、NE、Orc、Undead这些种族类名称发生变化,我们只需要修改工厂类Factory就可以了,也就是把耦合从Program转移到Factory

2.利用配置文件定义类型

  在配置文件APP.config中添加AppSetting(配置文件就是一个XML文件)

    <appSettings>
      <add key="Race" value="Human"/>
    </appSettings>

  在工厂类Factory中调用配置文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;//要添加这个引用
namespace SimpleFactory
{
    public class Factory
    {
        public static string race = ConfigurationManager.AppSettings["Race"];//获取配置文件的Race
        public static IRace GetRace()
        {
            FactoryType factoryType = (FactoryType)Enum.Parse(typeof(FactoryType), race);//将Race转换为枚举值
            switch (factoryType)
            {
                case FactoryType.Human:return new Human();
                case FactoryType.NE: return new NE();
                case FactoryType.Orc: return new Orc();
                case FactoryType.Undead: return new Undead();
                default:throw new Exception();
            }
        }
    }
    public enum FactoryType
    {
        Human, NE, Orc, Undead
    }
}

  Program:

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

namespace SimpleFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            IRace race1 = Factory.GetRace();
            race1.ShowKing();
            Console.Read();
        }
    }
}

  这样我们可以通过修改配置文件中的value来使Factory实例化不同的类并返回

3.利用反射对Factory工厂进行解耦

  在配置文件APP.config中再添加一个key

    <appSettings>
      <add key="Race" value="Undead"/>
      <add key="raceReflect" value="SimpleFactory,SimpleFactory.NE"/>
    </appSettings>

  Factory如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Reflection;

namespace SimpleFactory
{
    public class Factory
    {//反射实现解耦,不再代码中出现细节
        public static string raceReflect = ConfigurationManager.AppSettings["raceReflect"];//获取配置文件的Race
        public static IRace GetRaceReflect()
        {
            //写法一
            string assemblyName = raceReflect.Split(',')[0];
            string typeName = raceReflect.Split(',')[1];
            return (IRace)Activator.CreateInstance(assemblyName, typeName).Unwrap();

            //写法二
            //string [] raceReflectValue = raceReflect.Split(',');
            //Assembly assembly = Assembly.Load(raceReflectValue[0]);
            //Type type = assembly.GetType(raceReflectValue[1]);//基于类的完整名称找出类型
            //return (IRace)Activator.CreateInstance(type);//实例化
        }
    }
}

  Program:

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

namespace SimpleFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("-----------------------reflect----------------------------");
            IRace race2 = Factory.GetRaceReflect();
            race2.ShowKing();
            Console.Read();
        }
    }
}

  使用这种方法,Factory不会再出现Human, NE, Orc, Undead这些细节词,一切基于配置文件

   所以,当我们新增一个种族类的时候,只需要修改配置文件就可以调用这个类

原文地址:https://www.cnblogs.com/wskxy/p/9231701.html