博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
步步为营 .NET 代码重构学习笔记 三、内联方法(Inline Method)
阅读量:6717 次
发布时间:2019-06-25

本文共 3689 字,大约阅读时间需要 12 分钟。

一、Inline  Method

概述

一个函数,其本体(method body)应该与其名称(method name)同样清楚易懂.

动机(Motivation)

以简短的函数表现动作意图,这样会使代码更清晰易读.但有时候你会遇到某些函数.其内部代码和函数名称同样清晰易读.也可能你重构了该函数,使得其内容和其名称变得同样清晰.果真如此,你就应该去掉这个函数,直接使用其中代码,间接可能带来帮助,但非必要的间接性总是让人不舒服.

作法(Mechanics)

1、检查函数,确定它不具多态性(is not ploymorphic)

如果subclass继承了这个函数,就不要将此函数inline化。因为subclass无法覆写(override)一个根本不存在的函数。

2、找出这个函数的所有被调用点。

3、将这个函数的所有被调用点都替换为函数本体(代码)。

4、删除该函数的定义。

示例

public class Inline    {        public string GetUserInfo(int Age)        {            return MoreThenTen(Age) ? "spring yang" : null;        }        public bool MoreThenTen(int Age)        {            return Age > 10;        }    }

 

改为:

public class Inline    {        public string GetUserInfo(int Age)        {            return Age>10 ? "spring yang" : null;        }    }

 

二、Inline Temp

概述

一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其它重构手法。

动机(Motivation)

Inline Temp多半是作为Replace Temp with Query的一部分来使用。惟一单独使用Inline Temp的情况是:你发现某个临时变量被赋予某个函数调用的返回值。一般来说,这样的临时变量不会有任何危害,你可以放心地把它留在那儿。但如果这个临时变量妨碍了其它重构手法---例如Extract Method,就应该将它inline化。

作法(Mechanics)

1、如果这个临时变量并未被声明为final,那就将它声明为final,然后编译。

这可以检查该临时变量是否真的只被赋值一次。

2、找到该临时变量的所有引用点,将它们替换为为临时变量赋值的语名中的等号右侧表达式。

3、每次修改后,编译并测试。

4、修改完所有引用点之后,删除该临时变量的声明式和赋值语名。

示例

public class Inline    {        public double GetUserSalary(string name)        {            double salary = UserSalary(name);            return salary * 5;        }    }

 

改为:

public class Inline    {        public double GetUserSalary(string name)        {            return UserSalary(name) * 5;        }    }

 

三、Replace Temp with Query

概述

程序以一个临时变量(temp)保存某一表达式的运算结果。将这个表达式提炼到一个独立函数(查询式,query)中。将这个临时变量的所有(被引用点)替换为对新函数的调用。新函数可被其它函数使用。

动机(Motivation)

临时变量的问题在于,它们是暂时的,而且只能在所属函数内使用。由于临时变量只有在所属函数内才可见,所以它们会马驱使你写出更长的函数,因为只朋这样你才能访问到想要访问的临时变量。如果把临时变量替换为一个楂询式(query method),那么同一个class中的所有函数都将可以获得这份信息。这将带来极大帮助,使你能够为这个class编写更清晰的代码。

作法(Mechanics)

1、找出只被赋值一次的临时变量。

如果某个临时变量被赋值超过一次,考虑使用Split Temporary Variable将它分割成多个变量。

2、将该临时变量声明为final。

3、编译。

这可确保临时变量的确只被赋值一次。

4、将对该临时变量赋值的语名的等号右侧部分提炼到一个独立函数中。

首先将函数声明为private,日后你可能会发现有更多class需要使用它,彼时你可轻易放松对它的保护。

确保提炼出来的函数无任何连带影响,也就是说该函数并不修改任何对象内容。如果它有连带影响,就对它进行Separate Query from Modifier。

示例

public double GetPrice()        {            int area = _width * _higth;            double discount;            if (area > 1000) discount = 0.9;            else discount = 1;            return area * discount;        }

 

改为:

public double GetPrice()        {            return GetArea() * GetDiscount();        }        public double GetDiscount()        {            double discount;            if (GetArea() > 1000) discount = 0.9;            else discount = 1;            return discount;        }        public int GetArea()        {            return _width * _higth;        }

 

四、Introduce Explaining Variable

概述

将复杂表达式的结果放进一个临时变量,以此变量名称来解释表达式用途。

动机(Motivation)

表达式有可能非常复杂而难以阅读,临时变量可以帮助你将表达式分解为比较容易管理的形式。

作法(Mechanics)

1、声明一个final临时变量,将待分解之复杂表达式中的一部分动作的运算结果赋值给它。

2、将表达式中的运算结果这一部分,替换为上述临时变量。

如果被替换的这一部分在代码中重复出现,你可以每次一个,逐一替换。

示例

double _width, _higth;        public double GetPrice()        {            return _width * _higth - Math.Max(0, _width - 1000) * _higth * 0.03 + Math.Min(_width * _higth * 0.1, 100);        }

 

改为:

 

double _width, _higth;        public double GetPrice()        {            return NormalPrice() - QuantityDiscount() + Shipping();        }        public double NormalPrice()        {            return _width * _higth();        }        public double QuantityDiscount()        {            return Math.Max(0, _width - 1000) * _higth * 0.03;        }        public double Shipping()        {            return Math.Min(NormalPrice() * 0.1, 100);        }

总结

将复杂表达式分解成清晰易读的若干方法以使程序可读性更强。

转载于:https://www.cnblogs.com/springyangwc/archive/2011/05/16/2048105.html

你可能感兴趣的文章
java多线程(同步与死锁问题,生产者与消费者问题)
查看>>
Atitit. atiOrder Order 订单管理框架的设计
查看>>
5-2-三元组顺序表(稀疏矩阵)-数组和广义表-第5章-《数据结构》课本源码-严蔚敏吴伟民版...
查看>>
【系统】CentOS、Ubuntu、Debian三个linux比较异同
查看>>
浅谈web网站架构演变过程
查看>>
php socket 模型及效率问题
查看>>
路漫漫其修远兮,吾将上下而求索——小酌重构系列[0]开篇有益
查看>>
[javaSE] 位运算符(&|^)
查看>>
自定义控件 横向滑动控件 总结
查看>>
keil l251 command summary --Lib
查看>>
Hibernate Cascade
查看>>
java的技术调用栈图示例
查看>>
IIS 之 功能详解
查看>>
C#Base64编码
查看>>
spring主要的作用?
查看>>
Storm概念学习系列之storm的特性
查看>>
JQuery------$.get()和$.post()传递数据的使用方法
查看>>
Atitti 数据库事务处理 attilax总结
查看>>
Android中动态设置GridView的列数、列宽和行高
查看>>
oracle中修改表名
查看>>