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

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

  书中会列举出很多的坏味道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。

 

 

代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> 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的方法。

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

  

代码
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> 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();
        }
    }
}

 

 

  

 

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

  

你可能感兴趣的:(设计模式,LINQ)