标签 重构 下的文章

在你重构之前

本文翻译自"Before You Refactor",来自于《97 Things Every Programmer Should Know》一书中的某个章节。

在某些时候,每个程序员都需要重构现有的代码。不过在你动手之前,请考虑一下下面的内容,因为这可以节省你和他人的大量时间(以及痛苦)。

· 重构开始的最好方式就是对现有代码库及其测试代码进行总结和评估。

这将帮助你理解现有代码的优点和不足,你也可以确保将优点保留住并避免错误。我们总是认为自己做的可以比现有系统更好…直到最终我们没能拿出更好的系统,甚至做得比系统的前身更糟,因为我们没有从现有系统的错误中汲取教训。

· 抵御重写一切的诱惑

最好尽可能多地重用现有代码。无论这些代码有多么丑陋,它们毕竟是经过评审和测试过的。扔掉旧代码,特别是那些运行在生产环境中的代码,意味着你扔掉了经过数月(或者数年)测试且久经沙场的代码,或许这些代码中还包含了一些你所不知道的特定的应对方案和Bugfix。如果你没有考虑到这些,你写的新代码最终就会出现出同样诡秘的bugs,而这些Bug在旧代码中都已经被Fixed了。这将浪费大量时间、精力以及多年来积累的知识。

· 多次增量改变优于一次巨大改变

增量改变可以让你更容易地通过诸如测试等反馈来评估对系统的影响。做出一次改变就导致上百个测试失败,这可不是什么好玩的事。这可能让你更加沮丧,压力更大,并会相应地导致错误的决策。三两个测试失败容易对付,并且也容易管理。

· 每次迭代后,确保现有的测试通过

如果现有的测试无法覆盖你所做出的改动,那就增加测试。不要不经思考就扔掉针对旧代码的测试。表面上其中的一些测试似乎不适合你新设计了,不过深入分析这个特殊的测试被添加进来原因是非常值得的。

· 个人喜好和自大不应该成为障碍  

如果东西没有损坏,为什么要去修正它呢? 代码风格或结构不满足你的个人喜好,这不是一个重构的正当理由。认为你会做的比之前的程序员更好同样也不是一个正当理由。

· 新技术不足以成为重构的理由 

因为当前的代码落后于今天所有时髦的新技术,并且相信一门新语言或一个新框架可以使代码更优雅,这些都是最糟糕的重构理由。除非成本效益分析表明一门语言或一个框架将在功能性、可维护性以及生产力方面带来显著的提升,否则最好不要理会它。

· 请记住:人会犯错误 

重构并不总是保证新代码一定就更好,或者与以前的代码一样好。我看过并且亲身参与过许多次失败的重构尝试。漂亮并没有错,犯错的是人。

By Rajith Attapattu

 

经典设计原则背后的本质

近一段时间重读了一些经典书籍,诸如《敏捷软件开发:原则、模式与实践》、 《程序员修炼之道》、《Unix编程艺术》等。这些书中关于如何衡量或评价一个类或函数设计好坏的几个原则(Principle)让人印象深刻。《敏捷软件开发》中谈到了SRPOCPDIP; 程序员修炼之道则以DRY、“正交性”为话题展开;《Unix编程艺术》围绕紧凑性、SPOT、分离等阐述作者立场。这么多经典原则,如何学习把握?我们不妨来挖掘一下这些新设计原则背后的本质。

追本溯源,从计算机编程语言的发展历史来看,成熟的结构化程序设计语言(如C语言、Pascal等)要先于成熟的OO设计语言(C++、Java等)出现,那么其成熟的设计理论显然也是要早于后者的。这里就不能不提到经典结构化设计的代表作:《Structured Design: Fundamentals of a Discipline of Computer Program and System
Design
》,这本书出于1975年(年份来自维基百科,Amazon上卖的是1979年版)。说实话我也没有看过此书原版,不过书中的内容和思想早已被其他后继书籍引用和借鉴,我们在市面上能看到的关于结构化设计方面的书籍,尤其是中文书籍,多照搬了此书内容和思想,所以也算是间接学习到了。

书中对抽象、模块化、信息隐藏(黑盒)作了阐述,并介绍了数据流/控制流图、结构图等设计方法。特别是书中关于内聚(Cohesion)与耦合( Coupling)的讲解对之后的程序设计评价方法影响至深。我们一直常说高内聚低耦合的模块是良好的设计,这里的内聚和耦合概念的提出者恰是这本书的作者Larry L.Constantine。内聚和耦合这两个概念是用来评价一个module设计好坏的。module一词中文意为“模块”,模块一词的范围让人很难界定,关于module这个概念,书中给出了这样的解释:"A module is a lexically contiguous sequence of program statements, bounded by boundary elements, having an aggregate identifier.  Another way of saying this is that a module is a bounded, contiguous group of statements having a single name by which it can be referred to as a unit." 显然类或子程序(函数)是符合module的定义的。用内聚和耦合来评价类或子程序(函数)的设计是适合的。

关于Cohesion(CC2e 7.2小节)和Coupling(CC2e 5.3小节)的具体内容,这里就不细说了,《代码大全2》作者说的肯定比我好多了,另外维基百科中对coupling和cohesion的描述也很详尽。

以上所说的内聚和耦合其实就是我认为的以上诸多经典设计原则背后本质的东西。诸多设计原则应该可以看作是耦合和内聚概念在不同语言范式上下文情境下的延伸、再包装或升华。虽然有些原则说法发生变化了,但是本质却是一样的。比如: 单一职责原则(Single Responsibilty Principle, SRP) 显然是"功能内聚(Functional cohesion)"的另一种表述; 有些原则虽然无法直接与内聚耦合概念进行直接对号,比如依赖倒置原则(Dependency Inversion Principle,DIP),但是可以理解成追求低耦合的一种设计技法!

把握好内聚和耦合的核心理念,你将以不变应万变,你也会更深刻理解诸如OCP、DIP等新原则了。

俗话说“物以类聚”,这句同样适用于程序设计!一个module的设计如果有一处优点,那常常这个module也具备其他优点; 反之,如果发现这个module设计的一个缺点,那么离发现其他缺点也就不远了。

内聚与耦合的概念不仅仅适用于程序设计领域,在所有其他设计领域似乎同样普适!考虑对比一下一个具备电加热除霜功能的后视镜与一个普通后视镜在设计层面上的优点与不足吧!

发觉题目似乎有些夸张^_^。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats