`
zhang_xzhi_xjtu
  • 浏览: 524419 次
  • 性别: 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;
	}

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

相关推荐

    敏捷软件开发:原则、模式与实践.pdf

    Robert Cecil Martin 是软件开发领域里的一个响当当的名字。1970年代,他还是个年轻小伙子的时候就是一位有名的 UNIX 黑客。经过长期的开发实践后,他成了软件开发领域中的知名专家。1990年代初,Rational 软件公司...

    asp.net知识库

    [ASP.NET 2.0]PageParser.GetCompiledPageInstance中存在一个Bug 如何在DotNet 2的登录组件中检索用户的锁定状态及解锁? ASP.NET 2.0, 想说爱你不容易 SqlDataSource WEB控件:当DeleteCommandType= 遭遇 ASP.NET ...

    无懈可击的WEB设计第二版.pdf

    书中每一章的开头都给出了一个基于传统HTML技术的实例,然后对它进行重构,指出它的局限性,并利用XHTML和CSS对它进行改造。让您了解到怎样用整洁的HTML和CSS来取代那些臃肿冗余的代码,从而创建加载速度快、适应性...

    程序员为什么还要刷题-Software-Engineering-Practices-in-Data-Science.:这个Repo是关于软件工

    我要讨论的第一个实践是以干净和模块化的方式编写代码。 当您在行业工作时,您的代码可能会用于生产。 生产代码只是意味着,在生产服务器上运行的代码。 例如,当您在笔记本电脑上使用 Google 或 Amazon 等软件产品...

    Head First软件开发.pdf

    伟大的软件开发:让客户满意、收集需求:知道客户需要什么、项目规划:为成功而筹划、使用情节和任务:开始你实际的工作、足够好的设计:以良好的设计完成工作、构建你的软件代码:测试和连续集成:智者千虑必有一失...

    Reversing:逆向工程揭密

    记得第一次做与逆向有关的工作是2000年,当时由于项目的需要,做过一个钩子(hook)程序,用于截获一个第三方控件发出的消息,但是当时还不知道什么是逆向工程。第一次看到“逆向工程”这个词是在2001年的《机械工程...

    kendoDDD:基于Golang的DDD实践

    那应该怎么将一个大的系统合理有效的拆分成微服务呢?你需要了解领域驱动设计(DDD)。领域驱动设计因 Eric Evans 的著作而出名,它是一组思想、原则和模式,可以帮助我们基于业务领域的底层模型设计软件系统。开发...

    编程新手真言......

    4.9 学C千万不能走入的一个误区(其实JAVA比C难) 88 4.10 C抽象惯用法 90 4.11 C的抽象范式之OOP 91 4.12 C的观点:底层不需要直接抽象 93 4.13 指针:间接操作者 94 4.14 真正的typedef 95 4.15 真正的指针类型 95...

Global site tag (gtag.js) - Google Analytics