您的位置:首页 > 编程语言

《重构改善既有代码的设计》之重构列表--重新组织数据(二)

2012-12-18 11:02 246 查看

五、Replace Array with Object(以对象取代数组)

你有一个数组,其中的元素各自代表不同的东西。 以对象取代数组。对于数组中的每个元素,以一个字段表示。 动机 数组是一种常见的用以组织数据的结构。不过,它们应该只用于“以某种顺序容纳一组相似的对象”。有时候你会发现,一个数组容纳了多种不同的对象,这会给用户带来麻烦,因为他们很难记住像“数组的第一个元素是人名”这样的约定。对象就不同了,你可以运用字段名和函数名来传达这样的信息,因此你无需死记它,也无需依赖注释。而且如果使用对象,你还可以将信息封装起来,并使用Move Method为它们加上相关行为。 做法 1、新建类一个表示数组所拥有的信息,并在其中以public字段保存原先的数组。 2、修改数组的所有用户,让它们改用新类的实例。 3、编译、测试。 4、逐一为数组元素添加取值、设值函数。根据元素的用途,为这些访问函数命名。修改客户端代码,让它们通过访问函数取用数组内的元素。每次修改后,编译并测试。 5、当所有对数组的直接访问都转而都调用访问函数后,将新类中保存该数组的字段声明为private。 6、编译。 7、对于数组内的每一个元素,在新类中创建一个类型相当的字段。修改该元素的访问函数,令它改用上述的新建字段。 8、没修改一个元素,编译并测试。 9、数组的所有元素都有了相应字段后,删除该数组。

六、Duplicate Observed Data (复制“被监视数据”)

你有一些领域数据置身于GUI控件中,而领域函数需要访问这些数据。 将该数据复制到一个领域对象中。建立一个Observer模式,用以同步领域对象和GUI对象内的重复数据。 动机 一个分层良好的系统,应该将处理用户界面和处理业务逻辑的代码分开。之所以这样做,原因有一下几点:(1)你可能需要使用不同的用户界面来表现相同的业务逻辑,如果同时承担两种责任,用户界面会变得过分复杂;(2)与GUI隔离后,领域对象的维护和演化都会更容易,你甚至可以让不同的开发者负责不同部分的开发。 如果你遇到的代码是两层方式开发,业务逻辑被内嵌于用户界面中,你就有必要将行为分离出来。其中的主要工作就是函数的分解和搬移。但数据就不同了:你不能仅仅只是移动数据,必须将它复制到新的对象中,并提供相应的同步机制。 做法 1、修改展现类,使其成为领域累的Observer。 ? 如果尚未有领域类,就建立一个。 ? 如果没有“从展现类到领域类”的关联,就将领域类保存于展现类的一个字段中。 2、针对GUI类中的领域数据,使用Self Encapsulate Field。 3、编译、测试。 4、在事件处理函数中调用设置函数,直接更新GUI组件。 ? 在事件处理函数中放一个设值函数,利用它将GUI组件更新为领域数据的当前值。当然这其实没有必要,你只不过是拿它的值设定自己。但是这样使用设值函数,便是允许其中的任何动作得以于日后被执行起来,这是这一步的意义所在。 ? 进行这个改变时,对于组件,不要使用取值函数,应该直接取用,因为稍候后我们将修改取值函数,使其从领域对象(而非GUI组件)取值。设值函数也将做类似修改。 ? 确保测试代码能够触发新添加的事件处理机制。 5、编译、测试。 6、在领域类中定义数据及其相关访问函数。 ? 确保领域类中的设值函数能够触发Observer模式的通报机制。 ? 对于被观察的数据,在领域类中使用与展现类所用的相同类型(通常是字符串)来保存。后续重构中你可以自由改变这个数据类型。 7、修改展现类中的访问函数,将它们的操作对象改为领域对象(而非GUI组件)。 8、修改Observer的update(),使其从相应的领域对象中将所需数据复制给GUI组件。 9、编译、测试。

七、Change Unidirectional Association to Bidirectional(将单向关联改为双向关联)

两个类都需要使用对方特性,但其间只有一条单向连接。 添加一个反向指针,并使修改函数能够同时更新两条连接。 动机 开发初期,你可能会在两个类之间建立一条单向连接,是其中一个类可以引用另一个类。随着时间推移,你可能会发现被引用类需要得到其引用者以便进行某些处理。也就是说它需要一个反向指针。但指针是一种单向连接,你不肯能反向操作它。通常你可以绕道而行,虽然会耗费一些计算时间,成本还算合理,然后你可以在被引用类中建立一个函数专门负责此一行为。但是,有时候想绕过这个问题并不容易,此时就需要建立双向引用关系,或称为反向指针。如果使用不当,反向指针很容易造成混乱;但只要你习惯了这种手法,它们其实并不是太复杂。 “反向指针”手法有点棘手,所以在你能够自如运用以前,应该有相应的测试。通常我不花心思去测试访问函数,因为普通访问函数的风险并没有高到需要测试的地步,但本重构要求测试访问函数,所以她是极少数需要添加测试 重构手法之一。 做法 1、在被引用类中增加一个字段,用以保存反向指针。 2、决定由哪个类---引用端还是被引用端---控制关联关系。 3、在被控端建立一个辅助函数,其命名应该清楚指出它的有限用途。 4、如果既有的修改函数在控制端,让它负责更新反向指针。 5、如果既有的修改函数在被控端,就在控制端建立一个控制函数,并让既有的修改函数调用这个新建的控制函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: