你从某个对象中取出若干值,将它们作为某一次函数调用时的参数。改为传递整个对象。
动机:有时候,你会将来自同一对象的若干项数据作为参数,传递给某个函数。这样做的问题在于:万一将来被调用函数需要新的数据项,你就必须查找并修改对此函数的所有调用。如果你把这些数据所属的整个对象传给函数,可以避免这种尴尬的处境,因为被调用函数可以向那个参数对象请求任何它想要的信息。
除了可以使参数列更稳固外,Preserve Whole Object (保持对象完整)往往还能提高代码的可读性。过长的参数列很难使用,因为调用者和被调用者都必须记住这些参数的用途。此外,不使用完整对象也会造成重复代码,因为被调用函数无法利用完整对象中的函数来计算某些中间值。
不过事情总有2面:如果你传的是数值,被调用函数就只依赖于这些数值,而不依赖它们所属的对象。但如果你传递的是整个对象,被调用函数所在的对象就需要依赖参数对象。如果这会使你的依赖结构恶化,那么就不该使用Preserve Whole Object (保持对象完整)。
有的观点认为:如果被调用函数只需要参数对象的其中一项数值,那么只传递那个数值会更好。这个观点不能被认同:因为传递一项数值和传递一个对象,至少在代码清晰度上是一致的。更重要的考量应该放在对象之间的依赖关系上。
如果被调用函数使用了来自另一个对象的很多数据项,这可能意味着该函数实际上应该被定义在那些数据所属的对象中。所以,考虑使用Preserve Whole Object (保持对象完整)同时,你也该考虑Move Method(搬移函数)。
运用本项重构前,你可能还没有定义一个完整对象,那么就应该先使用Introduce Parameter Object (引入参数对象)。
还有一种常见情况:调用者将自己的若干数值作为参数,传递给被调用函数。这种情况下,如果该对象有合适的取值函数,你可以使用this取代这些参数值,并且无需操心对象依赖问题。
做法:1、对你的目标函数新添一个参数项,用以代表原数据所在的完整对象。
2、编译、测试。
3、判断哪些参数可被包含在新添得完整对象中。
4、选择上述参数之一,将被调用函数中原来引用该参数的地方,改为调用新添参数对象的相应取值函数。
5、删除该项参数。
6、编译、测试。
7、针对所有可从完整对象中获得的参数,重复上述过程。
8、删除调用端中那些带有被删除参数的代码。
9、编译、测试。