重构--引入参数对象

引入参数对象

某些参数总是很自然地同时出现。

动机

特定的一组参数总是被一起传递,可能是属于同一个class,也可能是不同的class。我们可以运用一个对象包装所有这些数据,就是是为了将这些数据组织在一起,也值得这么做。
新对象定义的访问函数可以使函数更容易理解。
发现一些可被移植至新建class的行为。
将共通行为移到新对象,可以减少很多重复代码。

做法

  • 新建一个class,用以表现你想替换的一组参数。 将这个设为不可变的( 不可被修改的)
  • 编译
  • 针对使用该组参数的所有函数, 实施Add Parameter, 以上述新建class 实体对象作为新添参数, 并将此一参数值设为null
  • 你可以保留修改前的旧函数, 并令它调用修改后的新函数。 然后逐一令调用端转而调用新函数, 最后再将旧函数删除
  • 对于Data Clump( 数据泥团) 中的每一项( 在此均为参数) , 从函数签名式( signature) 中移除之, 并修改调用端和函数本体, 令它们都改而通过「 新建 的参数对象」 取得该值。
  • 每去除一个参数, 编译并测试。
  • 将原先的参数全部去除之后, 观察有无适当函数可以运用Move Method 搬移到参数对象之中。
  • 是函数中的一个段落, 首先使用Extract Method 将该段落提炼为一个独立函数, 再搬移这一新建函数

范例

// Entry 实体函数
class Entry...
	private Date _chargeDate;
	private double _value;
	Entry (double value, Date chargeDate) {
		_value = value;
		_chargeDate = chargeDate;
	} 
	Date getDate(){
		return _chargeDate;
	} 
	double getValue(){
		return _value;
	} 
=============================>
// Account 保存了一组Entry 对象, 并有一个函数用来计算两日期间的帐项总量
class Account...
	double getFlowBetween (Date start, Date end) {
		double result = 0;
		Enumeration e = _entries.elements();
		while (e.hasMoreElements()) {
		Entry each = (Entry) e.nextElement();
		// 把这段判断移到DateRange中去
		if (each.getDate().equals(start) ||
			each.getDate().equals(end) ||
			(each.getDate().after(start) && each.getDate().before(end))){
				result += each.getValue();
			}
		} 
			return result;
		} 
		private Vector _entries = new Vector();
// 不过, 自从我得知Range 模式[Fowler, AP]之后, 我就尽量以「范围对象」 取而代之。 
client code...
	double flow = anAccount.getFlowBetween(startDate, endDate);
======================================================>
class DateRange {
	// 把DateRange class 设为不可变, 也就是说, 其中所有值域都是final
	private final Date _start;
	private final Date _end;
	// 只能由构造函数来赋值, 因此没有任何函数可以改其中任何值域值
	DateRange (Date start, Date end) {
		_start = start;
		_end = end;
	}
	Date getStart() {
		return _start;
	} 
	Date getEnd() {
		return _end;
	} 
}
========================================>
class Account...
	double getFlowBetween (DateRange range) {
		double result = 0;
		Enumeration e = _entries.elements();
		while (e.hasMoreElements()) {
			Entry each = (Entry) e.nextElement();
			if (range.includes(each.getDate())) {
				result += each.getValue();
			}
		} 
		return result;
	}
class DateRange...
	...
	boolean includes (Date arg) {
		return (arg.equals(_start) ||
				arg.equals(_end) ||
				(arg.after(_start) && arg.before(_end)));
	}
	...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值