`
zhang_xzhi_xjtu
  • 浏览: 538387 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

实践中的重构21_给她一个好名字

 
阅读更多
名字的重要性实在是再怎么强调都不为过的。
为什么名字这么重要呢?我的看法是,构建维护系统过程中最重要的事情之一就是同时建立并维护系统的一致性概念模型。无论通过何种手段进行沟通,如语言,文档,代码,注释,最重要的是有一套沟通的基石。即沟通各方对概念的理解是相同的,当提及一个概念时,大家所指的事物是相同的,没有二义性,没有模糊性。最怕张三在说西瓜,李四以为是个芝麻,鸡同鸭讲。倘若如此,好的结果是沟通过程中就发现了问题,花掉些时间,大家重新讨论各自概念的所指,最终达成了一致。运气差的话,沟通过程中并没有发现问题,各方都以为对方理解了自己的想法,于是大家都欢欢喜喜的做事情去了,终于在某一个时间点,才会惊喜的发现事情做的和预想的不一样,一些埋怨,指责,沟通后又重新开工了,可惜的是这个债务还起来是比较痛苦的,因为利息是驴打滚的。
概念是一个高度抽象的东西,看不见摸不着,难以把握,可以具化概念的一个工具就是给她命名,方便大家记忆理解。该命名代表了该概念,因此,命名应该是精确清晰的。如在一个系统中,有用户这样一个概念,那么我们既然已经命名了它的名字为user,那么请不要用诸如people,customer等等相似的名字来混淆视听。
概念的搭建并不是一件容易的事情,各个群体,业务方,开发方,测试方,运维方都有自己的方言。如果是跨团队跨公司合作的话,问题就更严重了。在软件开发的各个阶段,为了建立维护一套概念模型,都是要花费一定的时间的。
当一个系统搭建维护好了一个一致性概念模型后,对于以后的开发维护都是有着巨大的好处。
了解一个大型系统,一行行的读代码从时间上看是远远不够的,同时,系统代码又是不停动态变化的,因此该方法实际上不可行。概念模型相对比较稳定一些,先了解一个系统的概念模型(通过关键代码或者架构文档),然后在适当的时候深入一些细节,这样的方式更为可行一些。
常见的维护概念模型的工具有如下几种:文档,和人交流,代码注释,可执行代码。归根结底,代码才是一切的根本,和代码的距离越远,信息越容易不同步。这也是一直以来,业界认为自解释代码是最佳实践的原因之一。
另外,良好的概念模型和真实世界总是有着紧密关联的,有一个好名字,虽然并不意味着所有的代码都不需要一层层的深究到最底层,但是好的名字可以使开发维护时,凭借常识进行合理的猜测,更容易理解该命名背后的概念。如在一个People类的定义中有一个实例变量的名字是address,那么一个合理的猜测是该实例变量存储的是People的一个地址,而不是该People的手机号码。
如果有一行code是这样的:
String email=userInfo.getEmail();

那么我们会对这行代码做出什么样的判断呢?
我对这行代码的判断是从一个用户信息的模型中取出了用户的email。我相信大部分的人和我的猜测应该一致的。
但是很遗憾,这个猜测是错误的。同事给我指出在数据库中email的字段的存储值并不是该用户的email,该字段的说明是这样写的。如果该用户是用email注册的话,则该字段存储email值,否则存储该用户的手机号(系统目前只支持用email和手机号注册)。
有没有抓狂的感觉,我有。拜托,能不能让我的合理猜测是正确的。
还有另一个小例子。这个方法的功能是把一个大的列表划分为指定大小的一个子列表集合。
	public static List<List<String>> splitBigListBySize(List<String> list,
			final int size) {
		List<List<String>> packageList = new ArrayList<List<String>>();
		// 逐一分切
		List<String> bookList = null;
		// do something
		return packageList;
	}

从代码可以明显看出,当时写这个方法的程序员是知道该方法的应用场景的,于是,在方法体中不自觉的就用该场景中的概念去命名一个变量。问题是,该方法作为一个通用的工具方法,和任何业务场景应该是无关的,在该方法的概念空间中,只有传入的一个大列表,指定的子列表大小和需要返回的子列表这些概念。
我见过最让人抓狂的一个命名的例子就是,在一个类体系中,一个类的名字和其父类,父类的父类是完全一样的,除了包命名不一样,同时,这些代码还是同一个程序员写的。好大一个坑。
经常听到的一个比喻是,程序是程序员的孩子,那么,给程序中任何元素命名的时候,是否应该如同给自己小孩起名一样小心谨慎呢?
分享到:
评论

相关推荐

    cao_m.rar_cao MATLAB_嵌入维_相空间 重构_相空间重构Cao

    在IT领域,特别是数据分析和信号处理中,相空间重构是一个重要的概念,用于研究复杂非线性系统的动态行为。本文将详细解析"cao MATLAB_嵌入维_相空间 重构_相空间重构Cao"这一主题,并围绕提供的"cao_m.rar"压缩包...

    重构_改善既有代码的设计-中文完整版PDF

    重构的过程涉及各种操作,比如将一个设计不佳的代码重构为设计良好的代码,把某个类中的代码移到另一个类,或者将一些代码提取出来形成一个新的函数。重构时,作者会指导读者何时找到机会进行重构,以及如何实施这些...

    软件重构的思考与实践

    1. **两顶帽子**(Two Hats):这是一种思维方式,意味着开发者需要同时具备两种视角——一个是作为开发者,另一个则是作为重构者。开发者负责编写新功能,而重构者则关注代码质量的提升。 2. **单元测试**(Unit ...

    重构_改善既有代码的设计[中文高清版]

    这种做法旨在改善代码的质量、可读性和可维护性,是软件工程领域中一个重要的实践环节。重构的目的不仅仅是为了提升代码的美观度,更重要的是为了提高软件的长期价值,使代码更易于理解和修改,从而降低未来的维护...

    《重构——改善既有代码的设计》第一个案例代码

    在这个案例中,我们聚焦于一个影片出租点的程序,通过逐步的重构过程,来演示如何优化原始代码。 重构是一种在不改变代码外在行为的前提下,改进其结构的过程。这个过程通常伴随着单元测试,确保每次修改都不会破坏...

    一个delphi重构器.zip

    5. **提取类**:将一组相关的方法和数据打包到一个新的类中,以实现更好的封装和模块化。 6. **引入参数**:在函数调用处插入参数,并在函数定义处添加相应的处理,使函数更具通用性。 7. **删除冗余代码**:自动...

    重构_改善既有代码的设计[高清版]2010.4.pdf

    根据提供的文件信息,我们可以推断出这份文档主要围绕“重构——改善既有代码的设计”这一主题展开,...通过上述方法和技巧的应用,以及结合实际编程语言和技术的学习资源,开发者可以在实践中不断提高自己的重构能力。

    Java重构示例五.pdf

    在重构前的代码中,我们看到一个名为`LabelComparator`的类,它实现了`Comparator`接口并添加了`Serializable`特性。这个类包含了一个整型变量`sortType`用于表示排序方式(升序或降序)。`compare()`方法是`...

    java代码重构经验总结

    在上述代码片段中,可以看到一个典型的异常处理模式: ```java OutputStreamWriter out = null; java.sql.Connection conn = null; try { // 数据库操作 Statement stat = conn.createStatement(); ResultSet rs...

    31天代码重构快速优化代码

    重构是软件开发过程中的一个重要环节,它涉及到对现有代码结构的改进,以提高代码的可读性、可维护性和整体质量,而不会改变其外部行为。《31天重构速成》系列文章提供了31个具体的重构技巧,帮助开发者逐步掌握这一...

    重构:改善既有代码的设计

    《重构:改善既有代码的设计》是软件开发领域的一部经典之作,由著名的软件设计专家Martin Fowler撰写,并由...通过实践书中的重构手法,我们可以更好地应对复杂代码带来的挑战,打造出更健壮、更具弹性的软件系统。

    重构:改善既有代码的设计(英文原版和德语版)

    3. **重构技术**:这部分提供了大量具体的重构操作,每个操作都有一个简短的名字,便于记忆和交流。例如,抽取方法、提取类、移除中间人等,每种操作都有详细的步骤说明和示例,帮助读者理解和应用。 4. **设计原则...

    重构-改善既有代码的设计

    总之,《重构:改善既有代码的设计》是一本极具价值的技术书籍,它不仅系统地介绍了重构的概念和技术,还深入探讨了重构实践中的注意事项和最佳实践。对于希望提高代码质量和工作效率的程序员来说,这本书无疑是不可...

    中南大学软件学院架构jpetstore重构

    中南大学软件学院的一个实践项目,就是对经典的JPetStore应用进行重构,采用Struts2框架以提升其架构效率和代码质量。本文将深入探讨这一重构过程,以及Struts2框架在其中发挥的关键作用。 JPetStore是早期用于展示...

    《重构 改善既有代码的设计》

    - **重命名方法**:当一个方法的名字不能准确描述其功能时,应该考虑重命名。 - **提取方法**:将一段复杂的代码提取到一个新的方法中,以提高代码的可读性和可重用性。 - **替换算法**:当发现更高效或更简单的算法...

    oneisall基于react重构ONE一个移动端应用

    "oneisall基于react重构ONE一个移动端应用"的项目,主要展示了如何利用React技术栈对“ONE·一个”这个移动端应用进行重构。React是Facebook推出的一款用于构建用户界面的JavaScript库,尤其适合构建大型、高性能的...

Global site tag (gtag.js) - Google Analytics