zoukankan      html  css  js  c++  java
  • 简单工厂模式

    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这些细节词,一切基于配置文件

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

  • 相关阅读:
    配置 Sublime Text 用 Node.js 执行 JavaScript 程序
    KNN算法
    堆排序(heap sort)
    复原二叉树
    二叉树的广度优先遍历(层次遍历)
    二叉树(BT)相关
    BST(二叉搜索树)相关
    二叉树遍历(先序、中序、后序)
    排序算法
    查找算法
  • 原文地址:https://www.cnblogs.com/wskxy/p/9231701.html
Copyright © 2011-2022 走看看