Switch语句优化——用反射增强其扩展性

使用简单工厂和分层的思想对winform计算器项目进行了实践(项目代码见后期分享),在写工厂代码的时候用到了switch case语句对具体的计算方法进行了实例化代码如下

class OperateFactory
    {
        public static Operate CreateOperate(string oper)
        {
            Operate operate = null;
            switch (oper)
            {
                case "+":
                    operate = new AddOperate();
                    break;
                case "-":
                    operate = new MinusOperate();
                    break;
                case "*":
                    operate = new MutiplyOperate();
                    break;
                case "/":
                    operate = new DivideOperate();
                    break;
            }
            return operate;
        }
    }

从扩展性的角度来说,当增加新的算法时首先要增加一个算法类,然后必须在工厂里加一条case语句,这就破坏了开闭原则,使代码可维护性降低。所以需要将switch语句抽离出来——这就需要用到反射机制了。

修改类不符合开闭原则,但修改配置文件不会对类进行破坏啊。下面来看怎么通过反射机制来使switch语句更优雅。

首先需要把case的内容写到配置文件里,这样就不用再修改类了(关于配置文件见后期分享)代码如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  
  <!--读取算法类的上一级路径-->
  <!--我将算法类放在了类库里-->
  <connectionStrings>
    <add name="DAL" connectionString="DAL" />
  </connectionStrings>

  <!--可配置运算符-->
  <!--用键值对的方式将运行时用到的算符和算法类的类名绑定-->
  <appSettings>
    <add key ="+" value="AddOperate"/>
    <add key ="-" value="MinusOperate"/>
    <add key ="*" value="MutiplyOperate"/>
    <add key ="/" value="DivideOperate"/>
  </appSettings>
  
  
</configuration>

将case语句里的东西抽离并放到了配置文件里,接下来就要在工厂里调用配置文件来替换掉switch语句了(涉及到配置文件的操作,可去了解一下)。因为在这里用了反射机制和对配置文件的操作,所以对于工厂这个类需要做些前期准备:

在工厂类所属路径下右击“引用”,点击“添加引用”,将程序集引用进来,如图

然后引用命名空间,如图

做好了充足的准备,接下来就可以对工厂进行改造,建一个优雅的工厂了,代码如下

public class OperateFactory
    {
        public static Operate CreateOperate(string oper)
        {
            Operate operate = null;

            //通过“DAL"这个配置文件里定义好的名来读取算法类所在程序集
            string dalName = ConfigurationManager.ConnectionStrings["DAL"].ToString();
            //读取配置文件中的键,以获得算法类的值
            string fullName = ConfigurationManager.AppSettings[oper];
            //将程序集点儿类名拼接成字符串
            string className = dalName+"."+fullName;
            //通过反射实例化出拼接好的字符串点儿出来的类
            Assembly assembly = Assembly.Load(dalName);
            operate = (Operate)assembly.CreateInstance(className);

            return operate;
        }
    }

这样,工厂只负责读取配置文件并通过反射来实例化类,具体实例化哪些类就不是它所关心的事儿了,我们已将具体需要实例化的类放到了配置文件里,从而在不破坏类的前提下对算法进行扩展。

不得不感叹一下:”反射反射,程序员的快乐“啊。

发布了233 篇原创文章 · 获赞 22 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41026669/article/details/103533001