几年前,笔者参与过一个大项目,基于复杂的代码开发且客户不断变更功能需求。开发过程中,项目经理需要与客户不断沟通确认,因为根据项目早期的技术规划,新需求的部分功能无法实现或实现成本过高。
这种情况将开发者置于压抑状态下。作为一名软件开发人员,笔者并不认为编写软件应该如建造摩天大厦一番,随着项目的进行客户有越来越少的自由改变其想法。随着建筑业的发展,丝丝变化导致成本逐渐增加。
软件并非如此。开发者可以创建灵活的软件因为你不知道开发过程中软件会如何改变。
以下有五大方法用于编写灵活的代码。
避免继承
Go编程语言是为数不多的面向对象语言之一,其特殊性体现在不提供任何类继承方法或来自其他类的属性。虽然类层次结构是面向对象语言的基石,但是也会使代码更加死板。常见层次结构中所有类有着微妙的联系,改变其中任何一个类可能导致后代类发生变化或需要改变一个祖先类。遗传有助于代码耦合同时破坏后期修改代码能力,从而减少代码的灵活性。
除了创建死板的层次结构,对象继承也束在一起。如果一个属性或方法在类中命名却未定义,那么平台隐式搜索该祖先类以寻求匹配。可以自定义简单的方法覆盖或复杂的多重继承和模糊设计模式。避免继承意味着避免复杂内置行为的解决方案。
倾向组合
代替继承,Go语言建议对象组合。功能开发程序员都熟悉函数组成,组合对象是相似的。如继承,组合对象连接一个类到另一个,但不是调度隐式类,组合对象需指定何时或如何使用连接类方法和属性。这是会带来有力结果的一个小小不便。
使用组合对象,调度方法调用不同对象就变得微不足道了。可以根据不同情况下组合多个对象和调度不同对象,达到即使是多重继承也无法实现的功能。在不使用静态属性和全局变量的情况下还可以共享常用对象和状态。组合对象提供了细粒度控制代码,当不知未来代码会发生如何改变时,该方法提供了巨大的便利。
不要将偶然相似的代码抽象化
开发人员都学习了解DRY(Don’t Repeat Yourself)含义。它似乎变成了一个咒语,当我们编写代码时一旦发现相似的代码就会删除它。但是过于较真地删除重复数据往往不利于灵活性,特别是删除仅是表面的相似之处的代码。
打个比喻,两个变量值均为200。一个变量指在列表上项目指定的最大数值;另一个被用于检测HTTP响应是否成功。从表面来看,两个变量有相同的数值,人们很容易将MAX_ITEMS值设置为另一个变量,而不是设置数值200。但是如果将MAX_ITEMS设置等于HTTP_SUCCESS,那么是一个严重错误。两个结果值相同但是变量间并无联系。具有更好灵活性的代码需要有重复的代码。
以上的例子看起来很愚蠢,但是开发者开发时对模糊相似的代码会有下意识的反应。很多时候,相似性只是偶然和毫无意义的。
笔者对于表面相似的代码变得非常谨慎,吸取了以往教训,首先做出特定代码变化是避免误删代码的第一步。抽象化代码(无论是自己还是别人、以前还是现在)可做出乐观的假设,如果很多自以为相似的代码需要改变,那么它们都会以同样的方式改变。但这些笔者并没有遇到,且很多时候代码改变并不是以共享方式。
收缩抽象
抽象仍然是重要的,避免写抽象代码的一个方法是之前编写过代码后面不再写尽量减少抽象的代码的出现。编写少量抽象代码且集中起来,并且尽量不要调整代码位置。如果真的需要调整位置却不想改变代码的抽象所有的应用,那么更少的抽象对于修改版本更加容易。
收缩抽象的一个关键技巧是区分概念。Cognitect的CTO Rich Hickey已重新将“decomplet”注入现代词汇中,意为“散开。”通常,功能不同的代码会被放到同一个的代码块中。散开代码功能会产生抽象起到特定的作用,如设置一个标记,调用一个功能,然后取消标记。
小抽象也会有更广泛地应用。它们更容易相互组合。如果已习惯构建小的抽象代码,随着项目的不断成熟会有一个稳固的积累,使其更容易在不需要编写复杂代码情况下引入复杂的需求。
不要设想
更多的假设会让代码变得更加死板。避免设想使得代码更容易变化。
从目前我的项目中有一个实例:一个新链接应该在新标签中打开吗?有些人支持新标签,则有人反对,还有些都可以。通常情况下,这样的争论会通过权衡利弊,甚至做一些调查,遵循更好的选择。但在这种情况下,有一个假设我们没有做,链接没有自身行为方法,因为是我们配置行为。我们目前通过功能指定是否打开标签。
我们仅需修改少部分的代码来实现该选择功能。不同的开发者可以根据偏好设置不同的选项。如果用户想要关闭该选项,无须任何的代码改动也是可以做到的。如果用户不喜欢,我们也很容易配置符合每个用户的喜好。应用程序将会更加灵活因为我们避免了设想方式。
总结
根据笔者自身开发经历,通过以上技巧,开发的项目已可以跟上客户的变更请求。项目日益成熟,代码应该变得更加适应不断的变化。
英文来源:Five Tips for Writing Flexible Code
作者:Eric Shul
译者:屠敏,欢迎技术投稿、约稿,给文章纠错,请发送邮件tumin@csdn.net