博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重构-改善既有代码的设计(六)--重新组织函数
阅读量:6291 次
发布时间:2019-06-22

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

函数重构

重构有很大一部分都是在重构函数。尤其是长函数。这是问题的根源。以下是重构方法

Extract Method 提炼函数

提炼函数:(由复杂的函数提炼出独立的函数或者说大函数分解成由小函数组成)你有一段代码可以被组织在一起并独立出来。将这段代码放进一个独立函数,并让函数名称解释该函数的用途。

重构前

void printOwing() {       //print banner      System.out.println(“*********”);      System.out.println(“Banner”);      System.out.println(“*********”);      //print details      System.out.println ("name: " + _name);           System.out.println ("amount " + getOutstanding());   }

重构后

void printOwing()  {      printBanner();       printDetails(getOutstanding());   }     Void printBanner()  {      //print banner      System.out.println(“*********”);      System.out.println(“Banner”);      System.out.println(“*********”);  }  void printDetails (double outstanding)   {       System.out.println ("name: " + _name);       System.out.println ("amount " + outstanding);   }

Inline Method 内联函数

内联函数:(直接使用函数体代替函数调用 ) 一个函数调用的本体与名称同样清楚易懂。在函数调用点插入函数体,然后移除该函数

重构前

int getRating() {      return moreThanfiveLateDeliverise() ? 2 : 1;  }  bool moreThanfiveLateDeliverise() {      return _numberOfLateLiveries > 5;  }

重构后

int getRating(){       return _numberOfLateLiveries > 5 ? 2 : 1;  }

Inline Temp 内联临时变量

内联临时变量:(表达式代替临时变量)你有一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法。将所有对该变量的引用动作,替换为对它赋值的那个表达式自身

重构前

double basePrice = anOrder.BasePrice();  return basePrice(>1000);

重构后

return (anOrder.BasePrice() >1000);

Replace Temp with Query 以查询代替临时变量

以查询代替临时变量:(独立函数代替表达式)你的程序以一个临时变量保存某一个表达式的运算效果。将这个表达式提炼到一个独立函数中。将这个临时变量的所有引用点替换为对新函数的调用。此后,新函数就可以被其他函数调用。

重构前

double basePrice = _quantity*_itemPrice;  if (basePrice > 1000) {      return basePrice * 0.95;  else       return basePrice * 0.98;

重构后

if (basePrice() > 1000)      return basePrice() * 0.95;   else       return basePrice() * 0.98;   ……  double basePrice() {       return _quantity * _itemPrice;   }

注:这一条我始终不觉得合理。如果从性能上看。明显重构前的性能会比第二种更好。而且更容易理解

Introduce Explaining Variable 引入解释性变量

引入解释性变量:(复杂表达式分解为临时解释性变量)你有一个复杂的表达式。将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。

重构前

if (Platform.ToUpperCass().indexOf("MAC") > -1 && (Browser.ToUpperCass().indexOf("Ie") > -1) && WasInitalized() ) {      //do something   }

重构后

const bool imMacOs = Platform.ToUpperCass().indexOf("MAC") > -1;
const bool isIeBrowser = Browser.ToUpperCass().indexOf("Ie") > -1;
const bool wasInitalized = WasInitalized();
if (imMacOs && isIeBrowser && wasInitalized)
{

//do something

}

注:这一条和上上条并没有冲突。上上条指的是单纯地取值函数,如get方法。这一条针对无法理解的方法链

Split Temporary Variable 分解临时变量

分解临时变量:(临时变量不应该被赋值超过一次)你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立、对应的临时变量

重构前

double temp = 2 + (_height + _width);  Console.WriteLine(temp);  temp = _height * _width;  Console.WriteLine(temp);

重构后

const double perimeter = 2 + (_height + _width);  Console.WriteLine(perimeter);  const double area = _height * _width;  Console.WriteLine(area);

Remove Assigments to Parameters 移除对参数的赋值

移除对参数的赋值:(不要对参数赋值)代码对一个 参数赋值。以一个临时变量取代该参数的位置。

重构前

int discount (int inputVal, int quantity, int yearToDate){       if (inputVal > 50) inputVal -= 2;   }

重构后

int discount (int inputVal, int quantity, int yearToDate) {        int result = inputVal;        if (inputVal > 50) result -= 2;   }

注:如果传的是对象。除非你想要操作对象。否则就留下了bug的风险。因为对象传入方法被改变了。(这条也要具体情况具体使用)

Replace Method with Method object 函数对象取代函数

函数对象代替函数:(大函数变成类)你有一个大型函数,其中对局部变量的使用使你无法采用 Extract Method (提炼函数)。将这个大型函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。然后你可以在同一个对象中将这个大型函数分解为多个小型函数。

重构前

class Order...  double price() {       double primaryBasePrice;      double secondaryBasePrice;       double tertiaryBasePrice;       // long computation; ...   }

重构后

class Price {           double primaryBasePrice;          double secondaryBasePrice;           double tertiaryBasePrice;           public void price(){        // long computation; ...      或者可以采用static method

Substitute Algorithm 替换算法

替换算法:(函数本体替换为另一个算法)你想要把某个算法替换为另一个更清晰地算法。将函数本体替换为另一个算法。

重构前

String foundPerson(String[] people){       for (int i = 0; i < people.length; i++)  {           if (people[i].equals ("Don")){               return "Don";            }           if (people[i].equals ("John")) {             return "John";            }            if (people[i].equals ("Kent")){                   return "Kent";            }        }       return "";   }

重构后

String foundPerson(String[] people){       List candidates                = Arrays.asList(new String[] {"Don",   "John", "Kent"});       for (int i=0; i

注:如果可以使用更简单并清晰的方式。就果断换方式

转载地址:http://blcta.baihongyu.com/

你可能感兴趣的文章
Apache kafka 简介
查看>>
socket通信Demo
查看>>
技术人员的焦虑
查看>>
js 判断整数
查看>>
mongodb $exists
查看>>
js实现页面跳转的几种方式
查看>>
sbt笔记一 hello-sbt
查看>>
常用链接
查看>>
pitfall override private method
查看>>
!important 和 * ----hack
查看>>
聊天界面图文混排
查看>>
控件的拖动
查看>>
svn eclipse unable to load default svn client的解决办法
查看>>
Android.mk 文件语法详解
查看>>
QT liunx 工具下载
查看>>
内核源码树
查看>>
Java 5 特性 Instrumentation 实践
查看>>
AppScan使用
查看>>
Java NIO框架Netty教程(三) 字符串消息收发(转)
查看>>
Ucenter 会员同步登录通讯原理
查看>>