你有一笔数据项(data item),需要额外的数据和行为。

将这笔数据项变成一个对象。

class Order...
private string customer;

==>

class Order...
private Customer _customer;

class Customer...
private string _name;

动机

一开始你可能会用一个字符串来表示[电话号码]概念,但是随后你就会发现,电话号码需要[格式化]、[抽取区号]之类的特殊行为。当这些臭味开始出现,你就应该将数据值(data value)变成对象(object)。

作法

1. 为[待替换数值]新建一个class,在其中声明一个final值域,其型别和source class中的[待替换数值]型别一样。然后在新class中加入这个值域的取值函数(getter),再加上一个[接受此值域为参数]的构造函数。

2. 编译。

3. 将source class中的[待替换数值值域]的型别改为上述的新建class。

4. 修改source class中此一值域的取值函数(getter),令它调用新建class的取值函数。

5. 如果source class构造函数中提及这个[待替换值域](多半是赋值动作),我们就修改构造函数,令它改用新class的构造函数来对值域进行赋值动作。

6. 修改source class中[待替换值域]的设值函数(setter),令它为新class创建一个实体。

7. 编译,测试。

8. 现在,你有可能需要对新class使用Change Value to Reference(179)。

下面有一个代表[定单]的Order class,其中以一个字符串记录定单客户。现在,我希望改为以一个对象来表示客户信息,这样我就有充裕的弹性保存客户地址、信用等级等等信息,也得以安置这些信息的操作行为。Order class最初如下:

class Order...
public Order(String customer) {
_customer = cusomer;
}

public String getCustomer() {
return _customer;
}

public void setCustomer(String arg) {
_customer = arg;
}
private String _customer;

Order class的客户代码可能像下面这样:

private static int numberOfOrdersFor(Collection orders, String customer) {
int result = 0;
Iterator iter = orders.iterator();
while(iter.hasNext()) {
Order each = (Order)iter.next();
if(each.getCustomer().equals(customer)) result ++;
}
return result;

}

首先,我要新建一个Customer class来表示[客户]概念。然后在这个class中建立一个final值域,用以保存一个字符串,这是Order class目前所使用的。我将这个新值域命名为_name,因为这个字符串的用途就是记录客户名称。此外我还要为这个字符串加上取值函数(getter)和构造函数(constructor)。

class Customer {
public Customer(String name) {
_name = name;
}

public String getName() {
return _name;
}
private final String _name;
}

现在,我要将Order中的_customer值域的型别修改为Customer;并修改所有引用此一值域的函数,让它们恰当地改而引用Customer实体。其中取值函数和构造函数的修改都很简单;至于设值函数(setter),我让它创建一份Customer实体。
class Order...
public Order(String customer) {
_customer = new Customer(customer);
}

public String getCustomer() {
return _customer.getName();
}

public void setCustomer(String arg) {
_customer = new Customer(arg);
}
private Customer _customer;

设值函数需要创建一份Customer实体,这是因为以前的字符串是个实值对象(value object),所以现在的Customer对象也应该是个实值对象。这也就意味每个Order对象都包含自己的一个Customer对象。注意这样一条规则:实值对象应该是不可修改内容的--这便可以避免一些讨厌的[别名](aliasing)错误。日后或许我会想让Customer对象成为引用对象(reference object),但那是另一项重构手法的责任。现在我可以编译并测试了。

public String getCustomerName() {
return _customer.getName();
}

至于构造函数和设值函数,我就不必修改其签名(signature)了,但参数名称得改:
public Order(String customerName) {
_customer = new Customer(customerName);
}
public void setCustomer(String customerName) {
_customer = new Customer(customerName);
}

本次 重构到此为止。但是,这个案例和其他很多案例一样,还需要一个后续步骤。如果想在Customer中加入信用等级、地址之类的其他信息,现在还做不到,因为目前的Customer还是被作为实值对象(value object)来对待,每个Order对象都拥有自己的Customer对象。为了给Customer class加上信用等级、地址之类的属性,我必须运用Change Value to Reference(179),这么一来属于同一客户的所有Order对象就可以共享同一个Customer对象。马上你就可以看到这个例子。

转载于:https://www.cnblogs.com/pony1223/p/7565008.html

重构改善既有代码设计--重构手法19:Replace Data Value with Object (以对象取代数据值)...相关推荐

  1. 重构改善既有代码设计--重构手法11:Move Field (搬移字段)

    你的程序中,某个字段被其所驻类之外的另一个类更多的用到.在目标类建立一个新字段,修改源字段的所有用户,令它们改用新字段.        动机:在类之间移动状态和行为,是重构过程中必不可少的措施.随着系 ...

  2. 《重构-改善既有代码设计》读书笔记-重构篇

    2019独角兽企业重金招聘Python工程师标准>>> 重构定义 名词 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本.--<重 ...

  3. 重构-改善既有的代码设计-------代码的坏味道

    重构-改善既有的代码设计 代码的坏味道 神秘命名(Mysterious Name) 给函数.变量.模块和类命名时,要使它能清晰地表明自己的功能和用法,使得写下的代码直观明了. 常用重构手法为重命名,包 ...

  4. 重构改善既有代码设计

    目录 一.什么是重构 二.重构的目的和时机 2.1 目的 2.1.1 改进软件的设计 2.2.2 使软件更容易理解 2.2.3 帮助找到 BUG 2.2.4 提高编程速度 2.2 重构的时机 2.3 ...

  5. 重构-改善既有代码的设计:编写代码22宗罪(三)

    1 Duplicated  Code重复代码 不同的地方出现相同的程序结构: 如果你在一个以上的地点看到相同的程序结构,那么可以肯定:设法将它们和而为一,程序会变得更好.最常见的"重复代码& ...

  6. 重构:改善既有代码的设计(软件开发的不朽经典)

    重构:改善既有代码的设计(软件开发的不朽经典) 基本信息 作者: (美)Martin Fowler   译者: 熊节[同译者作品] 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:978 ...

  7. 《重构-改善既有代码的设计》读书笔记心得体会

    定义:(名词)对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本 (动词)使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构 重构的目的是使软件 ...

  8. 重构-改善既有代码的设计:重新组织数据的16种方法(六)

    重新组织数据: 1.Self Encapsulate Field 自封装字段 间接访问类的属性:你直接访问一个字段,但与字段之间的耦合关系逐渐变得笨拙.为这个字段建立取值/设值函数,并且只以这些函数来 ...

  9. 重构-改善既有代码的设计:重新组织函数的九种方法(四)

    函数过长或者逻辑太混乱,重新组织和整理函数的代码,使之更合理进行封装. 1. Extract Method 提炼函数 提炼函数:(由复杂的函数提炼出独立的函数或者说大函数分解成由小函数组成) 你有一段 ...

最新文章

  1. ATS 5.3.0缓存架构
  2. jforum中对各种servlet对象都进行了封装
  3. Dynamics CRM2015 2015版本可用的OData Query Designer工具
  4. ETL工具大全,你了解多少
  5. Android零基础入门第24节:自定义View简单使用
  6. flink 本地_Flink原理Apache Flink漫谈系列 State
  7. 3_4 IteratorMode 迭代器模式
  8. 【渝粤题库】陕西师范大学152206领导科学 作业(高起专、专升本)
  9. 表单提交防止恶意修改
  10. metasploit渗透测试指南_Metasploit渗透测试环境搭建与使用
  11. Android开发中的全屏背景显示方案
  12. Shader、Draw Call和渲染管线(Rendering Pipeline)
  13. db2 sqlcode常见及不常见
  14. DSP2812入门4——构建完整工程
  15. windows下采用批处理命令实现 FTP文件夹下载 包含子文件夹下载 Bat
  16. SVN图标丢失解决方法
  17. BaseFx实习小记(三)
  18. Matlab中用Simulink快速画Bode图及 .m 文件画Bode图
  19. B站弹幕爬取并制成词云
  20. java.lang.IllegalArgumentException介绍

热门文章

  1. 怎么使用PHPMailer实现邮件的发送??
  2. zeroc ice的概念、组成与服务
  3. 向“3+1” SQLServer2008集群增加磁盘
  4. 华为路由器防火墙配置命令总结(上)
  5. mysql中没有nvl求和sum_mysql使用sum()出现null的问题,各种总结
  6. Filecoin网络存储容量迎来3 EiB时刻
  7. 逾845.5万枚XRP从币安交易所转入未知钱包,价值超过496万美元
  8. 嘉楠发布阿瓦隆浸入式冷却矿机A1066I
  9. BP神经网络算法:将参数矩阵向量化
  10. Axure高保真学校后台管理作品管理教师管理资源审核学生管理家长管理权限管理资源管理web端后台模板管理教师审核统计分析教育后台管理系统学校后台管理系统校园后台管理系统