zoukankan      html  css  js  c++  java
  • 设计模式之-简单工厂模式

    简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
     
    就以之前玩过的一个游戏为例子,通过简单工厂来实现一系列功能。
    首先这个游戏分为5个门派(金,木,水,火,土),每个不同的门派拥有不同的技能。
     
    首先定义一个门派接口,然后分别定义几个实现门派。
        /// <summary>
        /// 门派接口
        /// </summary>
        public interface ISects
        {
            /// <summary>
            /// 技能
            /// </summary>
            void Skill();
        }
        /// <summary>
        /// 金系门派
        /// </summary>
        public class Gold : ISects
        {
            public void Skill()
            {
                Console.WriteLine("金系门派技能:金光乍现");
            }
        }
        /// <summary>
        /// 木系门派
        /// </summary>
        public class Wood : ISects
        {
            public void Skill()
            {
                Console.WriteLine("木系门派技能:摘叶飞花");
            }
        }
        /// <summary>
        /// 水系门派
        /// </summary>
        public class Water : ISects
        {
            public void Skill()
            {
                Console.WriteLine("水系门派技能:滴水穿石");
            }
        }

    接下来是调用:

        ISects gold = new Gold();
        gold.Skill();
    
        ISects wood = new Wood();
        wood.Skill();
    
        ISects water = new Water();
        water.Skill()

    我们来看一下结果:

    没有意外的得到了我们想要的结果,但是对于我们上端(调用端)而言,我们高度耦合了细节,也就违背了我们开发时经常挂在嘴边的"低耦合",那么现在我们遇到了这种问题,现在当然要来解决了。

    1.用简单工厂来解决我们遇到的问题

    而"简单工厂"就能很好的解决这类问题。

    我们只需要将创建对象这个动作转移到另一个地方即可。

    建立一个工厂类,专门为我们生产我们需要的对象。

        public class Factory
        {
            public static ISects CreateInstance(SectsType sectsType)
            {
                switch (sectsType)
                {
                    case SectsType.Gold:
                        return new Gold();
                    case SectsType.Wood:
                        return new Wood();
                    case SectsType.Water:
                        return new Water();
                    case SectsType.Fire:
                        throw new ArgumentException("没有Fire门派");
                    case SectsType.Soil:
                        throw new ArgumentException("没有Soil门派");
                    default:
                        throw new ArgumentException();
                }
            }
    
            public enum SectsType
            {
                Gold,
                Wood,
                Water,
                Fire,
                Soil
            }
        }

    然后调用方式如下:

        ISects gold = Factory.CreateInstance(Factory.SectsType.Gold);
        gold.Skill();
    
        ISects wood = Factory.CreateInstance(Factory.SectsType.Wood);
        gold.Skill();

    结果如下:

     

    上面所示就是用简单工厂很好的解决了我们的问题。

    2.简单工厂+配置文件 使得我们的项目变的可配置

    配置文件如下:

      <appSettings>
        <add key="SectsTypeName" value="Water"/>
      </appSettings>

    工厂内部创建对象的方法如下:

        private static string SectsTypeName = ConfigurationManager.AppSettings["SectsTypeName"];
        public static ISects CreateInstanceWithConfig()
        {
            switch (Enum.Parse(typeof(SectsType), SectsTypeName))
            {
                case SectsType.Gold:
                    return new Gold();
                case SectsType.Wood:
                    return new Wood();
                case SectsType.Water:
                    return new Water();
                case SectsType.Fire:
                    throw new ArgumentException("没有Fire门派");
                case SectsType.Soil:
                    throw new ArgumentException("没有Soil门派");
                default:
                    throw new ArgumentException();
            }
        }

    结果如下:

    3.简单工厂+配置文件+反射 使得我们的项目变得可扩展

    配置文件如下:

      <appSettings>
        <add key="SectsTypeNameWithReflect" value="SimpleFactory,SimpleFactory.Wood"/>
      </appSettings>

    工厂类创建对象方法代码如下:

            private static string SectsTypeNameWithReflect = ConfigurationManager.AppSettings["SectsTypeNameWithReflect"];
            public static ISects CreateInstanceWithReflect()
            {
                string assemblyName = SectsTypeNameWithReflect.Split(',')[0];
                string typeName = SectsTypeNameWithReflect.Split(',')[1];
                return (ISects)Activator.CreateInstance(assemblyName,typeName).Unwrap();
            }

    调用代码:

        ISects wood = Factory.CreateInstanceWithReflect();
        wood.Skill();

    结果如下:

    简单工厂到这里,可所谓是已经非常强大了,当我们需要添加一个新的门派的时候,只需要要添加新的门派类即可,当有一个第三方类库也实现了我们的门派接口时,我们只需要将它的dll拷贝过来就行,然后就可以使用了,这才是真正做到了可扩展。

     源代码地址:https://github.com/houzhenhuang/DesignPattern

  • 相关阅读:
    smarty对网页性能的影响--开启opcache
    1stopt8.0 代码示例
    1stopt、matlab和python用morris、sobol方法实现参数敏感性分析
    MATLAB 实现sobol参数敏感性分析
    matlab中自带的sobol的函数提供的sobol序列
    matlab和fortran混合编程
    mathematic语法基础
    fortran常用语句--读写带注释文档、动态数组等语法
    fortran语言调用fortran写的dll
    C语言函数指针与 c#委托和事件对比
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/10346181.html
Copyright © 2011-2022 走看看