当对局部变量的引用无法使用Extract Method的时候,可以考虑将这个函数放入到一个单独的对象中去,如此一来,局部变量就变成了对象的字段,然后就可以在同一对象中将这个大型函数分解成小型函数。
如:在Order类中:
- package com.xuzengqiang.ssb.movie;
- public class Order {
- // .....
- private double price() {
- double primaryBasePrice;
- double secondaryBasePrice;
- double tertiaryBasePrice;
- // do something
- return 1.0;
- }
- }
这个时候就可以将price抽取出来作为一个单独的类,此时里面的局部变量就变成了这个类里面的字段。
- package com.xuzengqiang.ssb.movie;
- public class PriceCalculator {
- private final Test test;
- private double primaryBasePrice;
- private double secondaryBasePrice;
- private double tertiaryBasePrice;
- public PriceCalculator(Test test) {
- this.test = test;
- }
- public double price() {
- double result = 0.0;
- // do something
- return result;
- }
- // other ...
- }
做法:
1、建立一个新的class,根据待被处理的函数的用途给其命名。
2、在新的class中建立一个final值域,用来保存原先大型函数的对象,称为源对象。同时针对原函数的每个临时变量和每个参数,在新class中建立一个个对应的值域保存。
3、在新的class中建立一个构造函数,接收原对象及原函数的所有的参数作为参数。
4、在新的class中建立一个对应的方法,如上例中的price(),并将原函数中的代码拷贝进来。
5、编译,在原函数中利用new 新class().price()执行该方法。
例子:
- public int gamma(int inputValue, int quantity, int yearToDate) {
- int importantValue1 = inputValue * quantity + delta();
- int importantValue2 = inputValue * yearToDate + 100;
- if ((yearToDate - importantValue1) > 100) {
- importantValue2 -= 20;
- }
- int importantValue3 = importantValue2 * 7;
- return importantValue3 - 2 * importantValue1;
- }
修改:
新建一个class,在这个class中提供一个final值域保存原先的对象,将源函数中的每一个参数和每一个临时变量,也以一个个值域逐一保存。
Gamma:
- private final Test test;
- private int inputValue;
- private int quantity;
- private int yearToDate;
- private int importantValue1;
- private int importantValue2;
- private int importantValue3;
提供对应的构造函数
- public Gamma(Test test, int inputValue, int quantity, int yearToDate) {
- this.test = test;
- this.inputValue = inputValue;
- this.quantity = quantity;
- this.yearToDate = yearToDate;
- }
拷贝原gamma中的方法移动到新class中。整理之后就变成了:
- package com.xuzengqiang.ssb.movie;
- public class Gamma {
- private final Test test;
- private int inputValue;
- private int quantity;
- private int yearToDate;
- private int importantValue1;
- private int importantValue2;
- private int importantValue3;
- public Gamma(Test test, int inputValue, int quantity, int yearToDate) {
- super();
- this.test = test;
- this.inputValue = inputValue;
- this.quantity = quantity;
- this.yearToDate = yearToDate;
- }
- public int execute() {
- importantValue1 = inputValue * quantity + test.delta();
- importantValue2 = inputValue * yearToDate + 100;
- if ((yearToDate - importantValue1) > 100) {
- importantValue2 -= 20;
- }
- importantValue3 = importantValue2 * 7;
- return importantValue3 - 2 * importantValue1;
- }
- }
原函数中的gamma方法就变成了:
- public int gamma(int inputValue, int quantity, int yearToDate) {
- return new Gamma(this,inputValue,quantity,yearToDate).execute();
- }
当然你还可以继续对execute()中的方法进行重构。