当前位置:编程学习 > 网站相关 >>

改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)

1. Move Method (函数搬家)
解释:
        如果 ClassA 的某个函数对 ClassB 有过多的依赖, 可以考虑将这个函数搬到 ClassB 中, 在 ClassA 的这个函数中直接调用 ClassB中这个函数的返回值.

        这样做的好处是减少物件与物件之间的耦合度, 很多情况下这样做更利于进一步的重构.

冲动前:
00 class EmployeeSalary 

01 { 

02     private double baseSalary = 15000.0; 

03   

04     public double Salary(Employee employee) 

05     { 

06         return baseSalary + 10000 / employee.Level; 

07     } 

08     // other method with baseSalary 

09 } 

10 class Employee 

11 { 

12     public int Level { get; set; } 

13 }

冲动后:
00 class EmployeeSalary 

01 { 

02     private double baseSalary = 15000.0; 

03   

04     public double Salary(Employee employee) 

05     { 

06         return employee.Salary(baseSalary); 

07     } 

08     // other method with baseSalary 

09 } 

10 class Employee 

11 { 

12     public int Level { get; set; } 

13     public double Salary(double baseSalary) 

14     { 

15         return baseSalary + 10000 / Level; 

16     } 

17 }

2. Move Field (值域搬家)
解释:
      有一天发现公司原来计算员工工资的方法不合适了, 比如不是所有的员工起薪 (baseSalary) 都是一万五, 我想把 baseSalary 搬到 Employee 这个物件中作为员工的一个属性.

      这样做可使程序扩展性变得更好, 最明显的是我可以设置不同员工的起薪了.

冲动前:
00 class EmployeeSalary 

01 { 

02     private double baseSalary = 15000.0; 

03   

04     public double Salary() 

05     { 

06         double salary = baseSalary; 

07         //do some compution with salary 

08         return salary; 

09     } 

10 }

冲动后:
00 class EmployeeSalary 

01 { 

02     public double Salary(Employee employee) 

03     { 

04         double salary = employee.BaseSalary; 

05         //do some compution with salary 

06         return salary; 

07     } 

08 } 

09 class Employee 

10 { 

11     public double BaseSalary { get; set; } 

12 }

3. Extract Class (提炼类)
解释:
      当某个物件做的事情过多, 这样的物件往往含有大量的字段, 属性和方法. 应该由两个或更多个物件来分担这些责任, 这时需要使用 Extract Class.

冲动前:
00 class Employee 

01 { 

02     public double BaseSalary { get; set; } 

03     public double Level { get; set; } 

04   

05     public double Salary() 

06     { 

07         double salary = BaseSalary; 

08         //do some complex compution with salary 

09         return salary; 

10     } 

11 }

冲动后:
00 class EmployeeSalary 

01 { 

02     public double Salary(Employee employee) 

03     { 

04         double salary = employee.BaseSalary; 

05         //do some complex compution with salary 

06         return salary; 

07     } 

08 } 

09 class Employee 

10 { 

11     public double BaseSalary { get; set; } 

12     public double Level { get; set; } 

13   

14     public double Salary() 

15     { 

16         EmployeeSalary salary = new EmployeeSalary(); 

17         return salary.Salary(this); 

18     } 

19 }

4. Inline Class (将类内联)
解释:
      Inline Class 和 Extract Class 正好相反. 当一个物件没有做它应该做的事情, 还专门使用了另一个物件来协助它完成这个职责, 这时可以考虑使用 Inline Class.

      如上面所示的例子, 如果我觉得 Employee 这个物件本身就应该实现 Salary 的计算工作, 而不是专门写一个 Salary 的计算物件来帮助它计算, 可以使用 Inline Class 将 Salary 内联到 Employee 中去, 也就是"冲动后"的代码重构成"冲动前"代码的样子.

5. Hide Delegate (隐藏委托关系)
解释:
      试想这么一个情况: 有一个 Employee 类, 这个类中含有一个部门 (Department) 属性, 并且 Department 是一种类. 如果我想知道某职工所在部门的经理人是谁的时候, 我需要通过 xxEmployee.Department.Manger 来访问. 但这样做有个缺点是对于其它代码,  Department 是 public 的, 其它代码能够访问到 Department 里的其它特性. 可以在 Employee 类中写一个 GetManger() 方法进行封装, 在调用的时候只需要xxEmployee.GetManger() 就行了.

冲动前:
0 class Department 

1 { 

2     public string Manger { get; set; } 

3 } 

4 class Employee 

5 { 

6     public Department Department { get; set; } 

7 }

冲动后:
00 class Department 

01 { 

02     public string Manger { get; set; } 

03 } 

04 class Employee 

05 { 

06     private Department Department; 

07   

08     public string GetManger() 

09     { 

10         return Department.Manger; 

11     } 

12 }

6. Remove Middle Man (干掉中间人)
解释:
      这一条与上一条 Hide Delegate 是相反的. 当我们要访问 Department 的其它很多特性时, 我们用 Hide Delegate 写了一条条简单的委托访问函数, 当这些函数多到几乎访问遍了 Department 里的内容, 可以考虑使用 Remove Middle Man 方法将这些访问函数干掉.

      如上面的例子, 就是将"冲动后"的代码重构成"冲动前"代码

补充:综合编程 , 其他综合 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,