• 重构改善既有代码的设计(一)switch statements Virus


      《重构-改善既有代码的设计》是一本好书,值得大家去反复看几遍,对后面学习设计模式有很好的帮助。设计模式猛一看,会很晕,云里雾里的,所以可以从重构开始,一点一点改善代码的设计,然后重构到模式,这样可以理解的更透侧,更容易消化。

      书中会列举出很多的坏味道bad smell,然后重构这些bad smell,增加复用性。其中一个就是当你使用switch的时候,尤其是case的东西定义了枚举类型的话,很多时候都可以用面向对象的多态很好的解决。要不然就是当你多一个枚举值的时候,需要修改原来的每一个switch,在每个里面添加一个case。

      近来在写一段程序的时候,大概需求是员工,有几个种类的员工,工程师,销售人员。设计好数据库就直接使用代码生成工具,生成了一大堆代码,设计的时候考虑到工程师或者销售人员数据量会很大,所以就放在了两个表中。

      这样就生成连个类engineer和salesman,和一些类的操作代码,就是一些add、delete、modify和get。

      就开始写后面的业务代码了,写的过程中发现engineer和salesman还是有很多是一样的,比如说username、password、logonname、birthday等等,就在业务层定义了一个employee类,类里面有一个属性叫做employeeType,初始化employee的时候会赋值,就是表明当前员工是engineer还是salesman。

     

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.
    Text;

    namespace ConsoleApplication2
    {
        enum employeeType1
        {
            engineer,
            salesman
        }
        class employee11
        {
            private  employeeType _empType;
            private 
    int _id;
            
    public employee11(employeeType empType)
                : this(empType, 
    0)
            {

            }
            
    public employee11(int id)
                : this(employeeType.engineer, id)
            {

            }
            
    public employee11(employeeType empType, int id)
            {
                this._empType 
    = empType;
                this._id 
    = id;
            }
            
    public void PrintSalary()
            {
                switch (_empType)
                {
                    
    case employeeType.engineer:
                        engineer1 e 
    = new engineer1(); 
                        e.PrintSalary();
                        
    break;
                    
    case employeeType.salesman:
                        salesman1 s 
    = new salesman1();
                        s.PrintSalary();
                        
    break;
                }
            }
            
    public void PrintName()
            {
                switch (_empType)
                {
                    
    case employeeType.engineer:
                        engineer1 e 
    = new engineer1();
                        e.PrintName();
                        
    break;
                    
    case employeeType.salesman:
                        salesman1 s 
    = new salesman1();
                        s.PrintName();
                        
    break;
                }
            }
        }
        class engineer1
        {

            
    public  void PrintSalary()
            {
                Console.WriteLine("your salary 
    is {0}", 1000);
            }
            
    public void PrintName()
            {
                Console.WriteLine("your name 
    is {0}", "shiwenbin");
            }
        }
        class salesman1
        {
            
    public void PrintSalary()
            {
                Console.WriteLine("your salary 
    is {0}", 2000);
            }
            
    public void PrintName()
            {
                Console.WriteLine("your name 
    is {0}", "swb");
            }
        }
    }

      如果后面要添加一个新员工类型,比如说boss,这样的话,首先要修改枚举employeeType1,然后要建立一个boss类,然后写上操作代码,还要在员工类employee11中的所有switch中都添加一个case,判断是否boss,然后调用boss的方法。

      新添加一个员工类型,修改代码是必然的,但是可以控制在一定的范围内,代码应该对修改封闭,对增加开发,这也是一个代码设计原则。有一种办法,例如面向对象的多态,可以很好的解决这个问题,使得下次增加员工类型的话,只是修改枚举量和新建一个员工类,其他的什么都不用动了。只要将上面的类改造为下面的内容。

      

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.
    Text;

    namespace ConsoleApplication2
    {
        enum employeeType
        {
            engineer,
            salesman
        }
        class employee1
        {
            protected employeeType _empType;
            protected 
    int _id;
            
    public employee1(employeeType empType):this(empType,0)
            {

            }
            
    public employee1(int id):this(employeeType.engineer,id )
            {

            }
            
    public employee1(employeeType empType, int id)
            {
                this._empType 
    = empType;
                this._id 
    = id;
            }
            
    public virtual void PrintName()
            {

            }
            
    public virtual void PrintSalary()
            {

            }
            
    public virtual void Print()
            {
                Console.WriteLine("haha");
            }
            
    public override string ToString()
            {
                
    return string.Format("id is :{0}; type is {1}", _id, _empType);
            }
        }
        class engineer : employee1
        {

            
    public engineer(int id)
                : base(employeeType.engineer)
            {
                this._id 
    = id;
            }
            
    public engineer()
                : base(employeeType.engineer)
            {
            }
            
    public override void PrintName()
            {
                Console.WriteLine("i am {
    0}", _empType.ToString());
            }
            
    public override void PrintSalary()
            {
                Console.WriteLine("your salary 
    is {0}", 1000);
            }
            
    public override string ToString()
            {
                
    return string.Format("id is :{0}; type is {1}", _id, _empType);
            }
        }
        class salesman : employee1
        {

            
    public salesman(int id)
                : base(employeeType.salesman)
            {
                this._id 
    = id;
            }
            
    public salesman()
                : base(employeeType.engineer)
            {
            }
            
    public override void PrintName()
            {
                Console.WriteLine("i am {
    0}", _empType.ToString());
            }
            
    public override void PrintSalary()
            {
                Console.WriteLine("your salary 
    is {0}", 2000);
            }
            
    public override string ToString()
            {
                
    return string.Format("id is :{0}; type is {1}", _id, _empType);
            }
        }
        class Program
        {
            static void Main(string
    [] args)
            {
                engineer emp1 
    = new engineer(123);
                emp1.PrintName();
                emp1.PrintSalary();
                emp1.
    Print();
                Console.WriteLine(emp1.ToString());
                Console.WriteLine("
    ------------------------------");
                salesman emp2 = new salesman(456);
                emp2.PrintSalary();
                emp2.
    Print();
                Console.WriteLine(emp2.ToString());
                Console.WriteLine("
    ------------------------------");
                Console.ReadLine();
            }
        }
    }
      

      也就是利用了继承和虚函数来实现多态,来实现对修改封闭,对增加开放。

      

  • 相关阅读:
    【html】页面制作规范文档
    【jquery】blockUI 弹出层
    前端攻城师所要掌握的知识和技能
    【html】edm 邮件制作指南
    【css】教你如何写出高效整洁的 css 代码——css优化
    前端开发神器notepad++以及zen coding神级插件
    百度统计流量研究院——了解互联网行业基本数据分布和趋势
    【css】我的 css 框架——base.css
    通过扩展方法 链式方法 为MVC 3 视图添加验证
    使用正则表达式抓取博客园列表数据
  • 原文地址:https://www.cnblogs.com/virusswb/p/1690085.html
Copyright © 2020-2023  润新知