重构对象-Move Field搬移值域二
创始人
2025-05-29 12:44:04
0

重构对象-Move Field搬移值域二

1.搬移值域

1.1使用场景

如果我发现,对于一个field(值域),在其所驻class之外的另一个class中有更多函数使用了它,我就会考虑搬移这个field。
上述所谓「使用」可能是通过设值/取值(setting/getting)函数间接进行。我也可能移动该field的用户(某函数),这取决于是否需要保持接口不受变化。如果这些函数看上去很适合待在原地,我就选择搬移field。

1.2.如何做

  • 如果field的属性是public,首先使用Encapsulate Field封装值 将它封装起来。
  • 如果你有可能移动那些频繁访问该field的函数,或如果有许多函数访问某个field,先使用Self Encapsulate Field自动封装值 也许会有帮助
  • 编译,测试。
  • 在target class中建立与source field相同的field,并同时建立相应的设值/取值 (setting/getting)函数。
  • 编译target class。
  • 决定如何在source object中引用target object。
  • 一个现成的field或method可以助你得到target object。如果没有,就看能否轻易建立这样一个函数。如果还不行,就得在source class中新建一个field来存放target object。这可能是个永久性修改,但你也可以暂不公开它,因为后续重构可能会把这个新建field除掉。
  • 将所有「对source field的引用」替换为「对target适当函数的调用」。
  • 如果是「读取」该变量,就把「对source field的引用」替换为「对target取值函数(getter)的调用」;如果是「赋值」该变量,就把对source field的引用」替换成「对设值函数(setter)的调用」。
  • 如果source field不是private,就必须在source class的所有subclasses中查找source field的引用点,并进行相应替换。
  • 编译,测试。

1.3.示例

下面是Account class的部分代码

class Account...private AccountType _type;private double _interestRate;double interestForAmount_days (double amount, int days) {return _interestRate * amount * days / 365;}

我想把表示利率的_interestRate搬移到AccountType class去。目前已有数个函数引用了它,interestForAmount_days() 就是其一。
下一步我要在AccountType中建立_interestRate field以及相应的访问函数:

class AccountType...// 在新类中创建属性private double _interestRate;// 创建属性对应的get和set方法void setInterestRate (double arg) {_interestRate = arg;}double getInterestRate () {return _interestRate;}

这时候我可以编译新的AccountType class。
现在,我需要让Account class中访问此_interestRate field的函数转而使用AccountType对象,然后删除Account class中的_interestRate field。
我必须删除source field,才能保证其访问函数的确改变了操作对象,因为编译器会帮我指出未正确获得修改的函数。

  private double _interestRate;double interestForAmount_days (double amount, int days) {// 调用改为目标类中的属性return _type.getInterestRate() * amount * days / 365;}

使用Self Encapsulate(自我封装)
如果有很多函数已经使用了_interestRate field,我应该先运用Self Encapsulate Field

 class Account...private AccountType _type;private double _interestRate;double interestForAmount_days (double amount, int days) {return getInterestRate() * amount * days / 365;}private void setInterestRate (double arg) {// 多个位置使用了_interestRate变量_interestRate = arg;}private double getInterestRate () {// 多个位置使用了_interestRate变量return _interestRate;}

这样,在搬移field之后,我就只需要修改访问函数(accessors)就行了

   double interestForAmountAndDays (double amount, int days) {return getInterestRate() * amount * days / 365;}private void setInterestRate (double arg) {_type.setInterestRate(arg);}private double getInterestRate () {return _type.getInterestRate();}

如果以后有必要,我可以修改访问函数(accessors)的用户,让它们使用新对象。 Self Encapsulate Field 使我得以保持小步前进。如果我需要对做许多处理,保持小步前进是有帮助的。特别值得一提的是:首先使用Self Encapsulate Field 使我得以更轻松使用Move Method 将函数搬移到target class中。如果待移函数引用了field的访问函数(accessors),那么那些引用点是无须修改的。

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...