`

重构-改善既有代码的设计(一)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();
        }
    }
}

 

 

  

 

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

  

分享到:
评论

相关推荐

    重构-改善既有代码的设计

    3.10 Switch Statements(switch惊悚现身) 82 3.11 Parallel InheritanceHierarchies(平行继承体系) 83 3.12 Lazy Class(冗赘类) 83 3.13 Speculative Generality(夸夸其谈未来性) 83 3.14 ...

    重构-改善既有代码的设计 中文版

    3.10 Switch Statements(switch惊悚现身) 3.11 Parallel Inheritance Hierarchies(平行继承体系) 3.12 Lazy Class(冗赘类) 3.13 Speculative Generality(夸夸其谈未来性) 3.14 Temporary Field(令人迷惑的...

    重构-改善既有代码的设计+中文版

     Switch Statements switch语句   Parallel Inheritance Hierarchies 平行继承体系   Lazy Class 冗余类   Speculative Generality 理论上的一般性   Temporary Field 临时字段   Message Chains 消息链...

    重构-改善既有代码的设计(中文版)

     Switch Statements switch语句   Parallel Inheritance Hierarchies 平行继承体系   Lazy Class 冗余类   Speculative Generality 理论上的一般性   Temporary Field 临时字段   Message Chains 消息链...

    重构:改善既有代码的设计.[美]Martin Fowler.epub【文字版手机格式】

    重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码。多年前,正是本书原版的出版,使重构终于从编程高手们的小圈子走出,成为众多普通程序员日常开发工作中不可或缺的一部分。本书也因此成为与...

    重构——改善既有代码的设计

     Switch Statements switch语句   Parallel Inheritance Hierarchies 平行继承体系   Lazy Class 冗余类   Speculative Generality 理论上的一般性   Temporary Field 临时字段   Message Chains 消息链...

    重构改善既有代码的设计-Refactoring:Improving the Design of Existing Code

    ### 重构改善既有代码的设计 #### 一、重构的基本概念 重构是指在不改变软件外部行为的情况下,通过修改代码来优化其内部结构的过程。这一过程旨在提高代码的可读性、可维护性和可扩展性,使得软件开发人员能够...

    重构,改善既有代码的设计

     Switch Statements switch语句   Parallel Inheritance Hierarchies 平行继承体系   Lazy Class 冗余类   Speculative Generality 理论上的一般性   Temporary Field 临时字段   Message Chains ...

    重构 改善既有代码的设计

     Switch Statements switch语句   Parallel Inheritance Hierarchies 平行继承体系   Lazy Class 冗余类   Speculative Generality 理论上的一般性   Temporary Field 临时字段   Message Chains ...

    9-重构1

    《重构:改善既有代码的设计》是一本深入探讨重构技术的书籍,作者通过实际案例阐述了重构的重要性及其实施方法。书中提到的第一个案例详细展示了如何逐步对一个名为`statement()`的函数进行重构,包括分解、重组...

    Code Bad Smell Detector-开源

    该项目遵循Martin Fowler在其1999年的著作《重构:改善既有代码的设计》中提出的五种主要的代码坏味道概念: 1. **数据块(Data Clumps)**:当多个变量经常一起出现,可能意味着应存在一个新的数据结构来封装这些...

Global site tag (gtag.js) - Google Analytics