`

使用内部类完成"Replace Method with Method Object"(以函数对象取代函数)重构

阅读更多
    “Replace Method with Method Object”(以函数对象取代函数)是一种重新组织函数(也就是Java中的方法,在本文中函数和方法这两个词表示的意思相同)的重构方法。其做法是将函数放进一个单独的对象当中,使用这个单独对象的值域(filed)来替代原函数中的局部变量。这样做的好处是对于一个拥有较多较复杂的局部变量的函数来说,进行“extract method”重构变得较为容易。
    偷懒,直接使用“重构——改善既有代码设计【Martin Flower】”一书中这个没有什么逻辑性的例子(有一些改动):
public class ReplaceMethodWithMethodObject extends TestCase {
	int gamma(int inputVal, int quantity, int yearToDate) {
		int importantValue1 = (inputVal * quantity) + delta();
		int importantValue2 = (inputVal * yearToDate) + 100;
		if ((yearToDate - importantValue1) > 100) {
			importantValue2 -= 20;
		}
		int importantValue3 = importantValue2 * 7;
		
		return importantValue3 - 2 * importantValue1;
	}
	
	public int delta() {
		return 5;
	}
	
	public void testGamma() {
		assertEquals(875, new Gamma(this, 5, 6, 7).gamma());
	}
}

//outer class method object
class Gamma {
	private ReplaceMethodWithMethodObject rmwmb;
	private int inputVal;
	private int quantity;
	private int yearToDate;
	
	public Gamma(ReplaceMethodWithMethodObject rmwmb ,int inputVal, int quantity, int yearToDate) {
		this.rmwmb = rmwmb;
		this.inputVal = inputVal;
		this.quantity = quantity;
		this.yearToDate = yearToDate;
	}
	
	int gamma() {
		int importantValue1 = (inputVal * quantity) + rmwmb.delta();
		int importantValue2 = (inputVal * yearToDate) + 100;
		if ((yearToDate - importantValue1) > 100) {
			importantValue2 -= 20;
		}
		int importantValue3 = importantValue2 * 7;
		
		return importantValue3 - 2 * importantValue1;
	}
}

    代码使用JUnit进行单元测试,在测试方法中调用时将ReplaceMethodWithMethodObject对象本身的引用传入Gamma对象的gamma方法。
    其实这里可以使用内部类来进行该项重构,代码如下:
public class ReplaceMethodWithMethodObject extends TestCase {
	int gamma(int inputVal, int quantity, int yearToDate) {
		int importantValue1 = (inputVal * quantity) + delta();
		int importantValue2 = (inputVal * yearToDate) + 100;
		if ((yearToDate - importantValue1) > 100) {
			importantValue2 -= 20;
		}
		int importantValue3 = importantValue2 * 7;
		
		return importantValue3 - 2 * importantValue1;
	}
	
	private int delta() {
		return 5;
	}
	
	/*
	 * replace method with inner class method object(could be better than outer class!)
	 */
	class Gamma {
		private int inputVal;
		private int quantity;
		private int yearToDate;
		
		public Gamma(int inputVal, int quantity, int yearToDate) {
			this.inputVal = inputVal;
			this.quantity = quantity;
			this.yearToDate = yearToDate;
		}
		
		int gamma() {
			int importantValue1 = (inputVal * quantity) + delta();
			int importantValue2 = (inputVal * yearToDate) + 100;
			if ((yearToDate - importantValue1) > 100) {
				importantValue2 -= 20;
			}
			int importantValue3 = importantValue2 * 7;
			
			return importantValue3 - 2 * importantValue1;
		}
	}
	
	public void testGamma() {
		assertEquals(875, new Gamma(5, 6, 7).gamma());
	}
}

    使用内部类进行“Replace Method with Method Object”重构带来两点好处:一是调用重构后的对象的函数时不用再传入当前对象的引用(因为内部类对象自动持有其外围类对象的引用);二是重构函数中调用的原对象中的其他函数可以不用public(请对比两段代码,注意delta()函数的访问修饰符),因为在内部类中可以访问到其外围类的任何成员(包括private的方法)。
分享到:
评论

相关推荐

    重构-改善既有代码的设计

    6.8 Replace Method with Method Object(以函数对象取代函数) 135 6.9 Substitute Algorithm(替换算法) 139 第7章 在对象之间搬移特性 141 7.1 Move Method(搬移函数) 142 7.2 Move Field(搬移字段...

    重构-改善既有代码的设计 中文版

    6.8 Replace Method with Method Object(以函数对象取代函数) 6.9 Substitute Algorithm(替换你的算法) 第7章 在对象之间移动特性 7.1 Move Method(搬移函数) 7.2 Move Field(搬移值域) 7.3 Extract Class...

    重构:改善既有代码的设计.[美]Martin Fowler.epub【文字版手机格式】

    6.8 Replace Method with Method Object(以函数对象取代函数) 6.9 Substitute Algorithm(替换算法) 第7章 在对象之间搬移特性 7.1 Move Method(搬移函数) 7.2 Move Field(搬移字段) 7.3 Extract Class(提炼类) ...

    重构-改善既有代码的设计+中文版

     Replace Method with Method Object 用方法对象代替方法   Substitute Algorithm 替换算法  Chapter 7:Moving Features Between Objects 在对象之间移动特性  *Move Method 移动方法   Move Field 移动...

    编码中的21种代码坏味道

    Extract Method(110)、Replace Temp with Query(120)和 Introduce Parameter Object(295)等方法,但仍然有太多临时变量和参数,那就可以使用 Replace Method with Method Object(135)来将长函数分解成多个小...

    设计模式与重构(design pattern )

    3. 将函数参数对象化(Replace Parameter with Object):当一个函数接收多个参数且这些参数之间有关联时,可以创建一个新的对象来封装这些参数。 4. 移除重复代码(Remove Duplicate Code):找出并消除代码中的...

    代码优化的常见问题

    使用“Replace Method with Method Object”重构技术,将方法转换为一个具有自己状态和行为的对象。 7. **参数列表过长(Long Parameter List)**:长参数列表会使方法调用变得难看且不易理解。可以通过“Introduce...

    重构_改善既有代码的设计

    6. **参数对象(Replace Data Value with Object)** - 使用对象代替简单的数据值,这可以增加代码的灵活性和可扩展性。 7. **多态(Replace Type Code with Subclasses)** - 通过多态替代类型码,即使用继承和...

    重构与模式.pdf

    9. **移除设置器**(Remove Setting Method):如果一个对象的状态变化过于频繁,可以考虑移除设置器方法,改用构造函数或工厂模式初始化对象状态。 10. **引入中间类**(Introduce Middle Class):当两个类之间...

    《重构 改善既有代码的设计》之代码的坏味道

    - **解决方法**:可以尝试减少参数的数量,比如通过将参数组合成一个对象(Introduce Parameter Object),或者将某些参数替换为方法调用(Replace Parameter with Method)等方式。 6. **发散式变化 (Divergent ...

    PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据

    Replace Array with Object是一个常见的重构策略,特别是当数组中元素具有不同意义时。将数组替换为对象可以提高代码的清晰度和可读性。例如,如果一个数组包含电话号码,而电话号码需要格式化、验证等操作,创建一...

    代码TOP10的坏味道

    - **Replace Method with Method Object**: 如果函数中有大量的参数和临时变量,可以考虑使用这种方法来重构,即将这些参数和临时变量封装到一个类中,并使用这个类作为参数。 #### 4. Large Class (过大类) **过...

    31天代码重构速成 你必须知道的重构技巧

    Extract Method Object (提取方法对象) - **定义**:将方法内的复杂逻辑封装到单独的对象中。 - **目的**:提高代码的清晰度和可测试性。 - **适用场景**:当某个方法内部实现过于复杂时,应考虑提取为独立的方法...

    重构改善既有代码的设计

    - **多态代替类型码(Replace Type Code with Polymorphism)**:利用面向对象的多态性来替代条件语句中的类型检查和分支。 #### 实施重构的最佳实践 实施重构并非随意修改代码,而是需要遵循一定的原则和流程: ...

Global site tag (gtag.js) - Google Analytics