改善代码设计 —— 优“.NET技术”化物件之间的特性(Moving Features Between Objects)...

本文主要是介绍改善代码设计 —— 优“.NET技术”化物件之间的特性(Moving Features Between Objects)...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  系列博客

      1. 改善代码设计 —— 优化函数的构成(Composing Methods)

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

      3. 改善代码设计 —— 组织好你的数据(Composing Data)

      4. 改善代码设计 —— 简化条件表达式(Simplifying Conditional Expressions)

      5. 改善代码设计 —— 简化函数调用(Making Method Calls Simpler)

      6. 改善代码设计 —— 处理概括关系(Dealing with Generalization)

  1. Move Method (函数搬家)

  解释:

        如果 ClassA 的某个函数对 ClassB 有过多的依赖, 可以考虑将这个函数搬到 ClassB 中, 在 ClassA 的这个函数中直接调用 ClassB中这个函数的返回值.

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

  冲动前:

 
class EmployeeSalary
{
private double baseSalary = 15000.0 ;

public double Salary(Employee employee)
{
return baseSalary + 10000 / employee.Level;
}
// other method with baseSalary
}
class Employee
{
public int Level { get ; set ; }
}

  冲动后:

 
class EmployeeSalary
{
private double baseSalary = 15000.0 ;

public double Salary(Employee employee)
{
return employee.Salary(baseSalary);
}
// other method with baseSalary
}
class Employee
{
public int Level { get ; set ; }
public double Salary( double baseSalary)
{
return baseSalary + 10000 / Level;
}
}

  2. Move Field (值域搬家)

  解释:

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

    &nb上海企业网站设计与制作sp; 这样做可使程序扩展性变得更好, 最明显的是我可以设置不同员工的起薪了.

  冲动前:

 
class EmployeeSalary
{
private double baseSalary = 15000.0 ;

public double Salary()
{
double 上海企业网站制作style="color: #000000;"> salary = baseSalary;
// do some compution with salary
return salary;
}
}

  冲动后:

 
class EmployeeSalary
{
public double Salary(Employee employee)
{
double salary = employee.BaseSalary;
// do some compution with salary
return salary;
}
}
class Employee
{
public double BaseSalary { get ; set ; }
}

  3. Extract Class (提炼类)

  解释:

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

  冲动前:

 
class Employee
{
public double BaseSalary { get ; set ; }
public double Level { get ; set ; }

public double Salary()
{
double salary = BaseSalary;
// do some complex compution with salary
return salary;
}
}

  冲动后:

 
class EmployeeSalary
{
public double Salary(Employee employee)
{
double salary = employee.BaseSalary;
// do some complex compution with salary
return salary;
}
}
class Employee
{
public double BaseSalary { get ; set ; }
public double Level { get ; set ; }

public double Salary()
{
EmployeeSalary salary
= new EmployeeSalary();
return salary.Salary( this );
}
}

  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() 就行了.

  冲动前:

 
class Department
{
public string Manger { get ; set ; }
}
class Employee
{
public Department Department { get ; set ; }
}

  冲动后:

 
class Department
{
public string Manger { get ; set ; }
}
class Employee
{
private Department Department;

public string GetManger()
{
return Department.Manger;
}
}

  6. Remove Middle Man (干掉中间人)

  解释:

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

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

  7. Introduce Foreign Method (引入外加函数)

  解释:

      Introduce Foreign Method 有很深的 C#3.0 中扩展方法的味道, 但扩展方法比 Introduce Foreign Method 好在: 扩展方法就好象是被扩展的那个类型自己的方法一样, 而 Introduce Foreign Method 的函数还需要传递这个类型的参数, 但其实编译器编译扩展方法后还是会把参数传进去的, 扩展方法只是一种语法糖.

      它的主要目的是实现被调用的类中没有实现的功能, 注意在进行本项重构时, 如果引入一个外加函数, 这说明这个函数本应该在被调用的类中实现. 下面举一个简单到不能再简单的例子, 这个例子只是说明怎么使用 Introduce Foreign Method, 我并不是说 Int32类型就应该有一个 NextNum 的方法 , 并且实际中多数情况下这种重构用于引用类型微笑

  冲动前:

 
int num = 1 ;
// I want to get num's next
int nextNum = num + 1 ;

  冲动后:

 
int num = 1 ;
int nextNum = NextNum(num);

private static int NextNum( int arg)
{
return arg + 上海网站建设tyle="color: #000000;"> 1 ;
}

  8. Introduce Local Extension (引入本地扩展)

  解释:

      如果我不想使用 Introduce Foreign Method, 我觉得它就本来应该实现某某功能, 如果被调用的类不是密封 (sealed) 的话, 可以自定义一个数据类型, 继承这个类, 在自己定义的数据类型中实现我想要它实现的功能, 这就是 Introduce Local Extension.

转载于:https://www.cnblogs.com/waw/archive/2011/10/13/2210647.html

这篇关于改善代码设计 —— 优“.NET技术”化物件之间的特性(Moving Features Between Objects)...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/352278

相关文章

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议