`

使用内部类完成"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 移动...

    重构,改善现有代码——代码坏味道

    重构、代码坏味道和解决方法 在软件开发中,代码坏味道是一个常见的问题,会使代码变...Extract Method、Pull Up Method、Replace Temp with Query和Replace Method with Method Object都是解决代码坏味道的有力武器。

    编码中的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