代码的坏味道(3)——基本类型偏执(Primitive Obsession)
坏味道——基本类型偏执(Primitive Obsession)
特征
- 使用基本类型而不是小对象来实现简单任务(例如货币、范围、电话号码字符串等)。
- 使用常量编码信息(例如一个用于引用管理员权限的常量
USER_ADMIN_ROLE = 1)。- 使用字符串常量作为字段名在数组中使用。

问题原因
类似其他大部分坏味道,基本类型偏执诞生于类初建的时候。一开始,可能只是不多的字段,随着表示的特性越来越多,基本数据类型字段也越来越多。
基本类型常常被用于表示模型的类型。你有一组数字或字符串用来表示某个实体。
还有一个场景:在模拟场景,大量的字符串常量被用于数组的索引。
解决方法

大多数编程语言都支持基本数据类型和结构类型(类、结构体等)。结构类型允许程序员将基本数据类型组织起来,以代表某一事物的模型。
基本数据类型可以看成是机构类型的积木块。当基本数据类型数量成规模后,将它们有组织地结合起来,可以更方便的管理这些数据。
- 如果你有大量的基本数据类型字段,就有可能将其中部分存在逻辑联系的字段组织起来,形成一个类。更进一步的是,将与这些数据有关联的方法也一并移入类中。为了实现这个目标,可以尝试
以类取代类型码(Replace Type Code with Class)。 - 如果基本数据类型字段的值是用于方法的参数,可以使用
引入参数对象(Introduce Parameter Object)或保持对象完整(Preserve Whole Object)。 - 如果想要替换的数据值是类型码,而它并不影响行为,则可以运用
以类取代类型码(Replace Type Code with Class)将它替换掉。如果你有与类型码相关的条件表达式,可运用以子类取代类型码(Replace Type Code with Subclass)或以状态/策略模式取代类型码(Replace Type Code with State/Strategy)加以处理。 - 如果你发现自己正从数组中挑选数据,可运用
以对象取代数组(Replace Array with Object)。
收益
- 多亏了使用对象替代基本数据类型,使得代码变得更加灵活。
- 代码变得更加易读和更加有组织。特殊数据可以集中进行操作,而不像之前那样分散。不用再猜测这些陌生的常量的意义以及它们为什么在数组中。
- 更容易发现重复代码。

重构方法说明
以类取代类型码(Replace Type Code with Class)
问题
类之中有一个数值类型码,但它并不影响类的行为。

解决
以一个新的类替换该数值类型码。

引入参数对象(Introduce Parameter Object)
问题
某些参数总是很自然地同时出现。

解决
以一个对象来取代这些参数。

保持对象完整(Preserve Whole Object)
问题
你从某个对象中取出若干值,将它们作为某一次函数调用时的参数。
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);
解决
改为传递整个对象。
boolean withinPlan = plan.withinRange(daysTempRange);
以子类取代类型码(Replace Type Code with Subclass)
问题
你有一个不可变的类型码,它会影响类的行为。

解决
以子类取代这个类型码。

以状态/策略模式取代类型码(Replace Type Code with State/Strategy)
问题
你有一个类型码,它会影响类的行为,但你无法通过继承消除它。

解决
以状态对象取代类型码。

以对象取代数组(Replace Array with Object)
问题
你有一个数组,其中的元素各自代表不同的东西。
String[] row = new String[3];
row[0] = "Liverpool";
row[1] = "15";
解决
以对象替换数组。对于数组中的每个元素,以一个字段来表示。
Performance row = new Performance();
row.setName("Liverpool");
row.setWins("15");
引申阅读
欢迎继续阅读 代码的症与药 系列文章。
代码的坏味道(3)——基本类型偏执(Primitive Obsession)的更多相关文章
- Refactoring之——代码的坏味道(二)过大的类 &(三)基本类型偏执
1.1.2 Large Class(过大的类) 特征:一个类包含过多的字段.方法.代码行. 问题原因: 类通常一开始很小,但是随着程序的增长而逐渐膨胀. 类似于过长方法,程序员通常觉得在一个现存类中添 ...
- Bad Smell (代码的坏味道)
sourcemaking 如果一段代码是不稳定或者有一些潜在问题的,那么代码往往会包含一些明显的痕迹.正如食物要腐坏之前,经常会发出一些异味一样, 我们管这些痕迹叫做 "代码异味" ...
- Refactoring之——代码的坏味道(一)过长方法
1 代码的坏味道 重构一书中提到了22种代码的坏味道,大致可以分为几类. 识别代码的坏味道,有助于发现代码的潜在问题,从而可以有的放矢的修改现有代码,使之不断完善. 1.1 Bloaters(臭鲱,暂 ...
- 消灭 Java 代码的“坏味道”
消灭 Java 代码的“坏味道” 原创: 王超 阿里巴巴中间件 昨天 导读 明代王阳明先生在<传习录>谈为学之道时说: 私欲日生,如地上尘,一日不扫,便又有一层.着实用功,便见道无终穷,愈 ...
- 【重构】 代码的坏味道总结 Bad Smell (一) (重复代码 | 过长函数 | 过大的类 | 过长参数列 | 发散式变化 | 霰弹式修改)
膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...
- 重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改
膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...
- Chapter 3 :代码的坏味道
"如果尿布臭了,就换掉它." --Beck奶奶,论保持小孩清洁的哲学 代码的坏味道这一章集中论述该何时重构.具体的重构方法在后面的章节. "没有任何度量规矩比得上见识广博 ...
- 代码的坏味道(16)——纯稚的数据类(Data Class)
坏味道--纯稚的数据类(Data Class) 特征 纯稚的数据类(Data Class) 指的是只包含字段和访问它们的getter和setter函数的类.这些仅仅是供其他类使用的数据容器.这些类不包 ...
- 代码的坏味道(10)——发散式变化(Divergent Change)
坏味道--发散式变化(Divergent Change) 发散式变化(Divergent Change) 类似于 霰弹式修改(Shotgun Surgery) ,但实际上完全不同.发散式变化(Dive ...
随机推荐
- jQuery弹出提示信息简洁版(自动消失)
之前看了有一些现成的blockUI.Boxy.tipswindow等的jQuery弹出层插件,可是我的要求并不高,只需要在保存后弹出提示信息即可,至于复杂点的弹出层-可以编辑的,我是直接用bootst ...
- error C2678
自定义结构类型,为支持插入到stl set或者排序,一种方式是重载operator<运算符成员函数.如果忘记将函数标识为const,则在编译时会报 6>c:\program files ( ...
- (转载)H.264码流的RTP封包说明
H.264的NALU,RTP封包说明(转自牛人) 2010-06-30 16:28 H.264 RTP payload 格式 H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) ...
- SQL Server恢复软件 Stellar Phoenix sql recovery
SQL Server恢复软件 Stellar Phoenix sql recovery http://www.stellarinfo.com/ http://www.stellarinfo.com/ ...
- 在MySQL的InnoDB存储引擎中count(*)函数的优化
写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...
- TODO:MongoDB MySQL数据库备份
TODO:MongoDB MySQL数据库备份 1. MongoDB使用命令备份 mongodump进行整个数据库备份,主要用到的命令参数: -d 要备份的数据库 -o 输出的路径 ./mongodu ...
- Android开发学习之路-Volley源码解析
从简单的StringRequest入手看看Volley的工作机制. 先简单说下Volley的用法: ① 获取一个RequestQueue mRequestQueue = Volley.newReque ...
- 2013 duilib入门简明教程 -- 结合win32和MFC (16)
虽然duilib自带在MFC中使用duilib的Demo,但只是MFC窗口和duilib窗口不重叠的情况.如果要在MFC窗口中嵌入duilib控件,或者在duilib控件中嵌入MFC的控件的话 ...
- C#设计模式-建造者模式
在软件系统中,有时需要创建一个复杂对象,并且这个复杂对象由其各部分子对象通过一定的步骤组合而成. 例如一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象,它是由C ...
- javascript运动系列第九篇——碰撞运动
× 目录 [1]碰撞检测 [2]无损碰撞 [3]有损碰撞 前面的话 碰撞可以分为碰壁和互碰两种形式,上篇介绍了碰壁运动,本文将从浅入深地介绍碰撞运动的互碰形式 碰撞检测 对于互碰形式的碰撞运动来说,首 ...