刚开始干这一行的时候,对代码的复用有很高的热情。那时候总是希望自己写出的function、class、模块都是可以复用的,能够优美的解决所有问题。但是往往事于愿违,设计的变更、需求的变更、种种没有预料的情况最终把自己的代码摧毁的面目全非。有时一个简单的function会出现各种不同的版本,SendMessage、SendMessage2、SendMessageEx……在注释中说明其间微妙的区别。复用的计划最终破产。经历打击后,又走向另一个极端:使用copy-paste解决问题。不在乎代码的复用性,放弃优美,走向彻底的实现主义。各种bad smell不断出现在代码中,疯狂的复制粘贴,然后稍加修改。一旦变更,到处修改。面对需求变更、产品升级、杂乱纠缠的代码、过时的文档,真是一种痛苦的经历。
代码复用到底能不能做到呢,怎样才能做到复用呢?
代码复用要求设计具有较高的质量
设计和编写可以复用的代码不是一件容易的事情。简单的说,就是要在需求,概念和最终的实现之间建立一种简单的关系[The Aspects Blog]。一个概念或者需求最好能在实现中有一个直接的体现。比如说,设计一个公司的管理系统,公司里有雇员,那么就设计一个Employee类,表示雇员这个概念。雇员有工资,那么就为这个Employee类加上一个Salery属性,表示雇员的工资。需求和实现之间的关系最理想的情况下应该是1:1,即一个需求对应一个唯一的实现。这样,当需求变化的时候,需要修改的实现也只有一处。这样的情况下,代码的复用性也是最好的,同一个功能只用一份代码来完成。
“需求:实现=1:1”是一个最优状态,达到这个状态首先要对需求有清楚的了解,尽量排除需求的含糊性,这一点是基础。其次在设计上要遵守一些最基本的原则,避免不合理的依赖关系。达到这个1:1很难,一般都会根据具体情况有所权衡。
在设计的不同阶段应该采用不同的抽象层次,不能过早的将问题具体化。具体化的时间过早,往往就意味着一个需求会对应多个实现。一些设计者往往不注重抽象,急于将功能点落实,采用的设计方式经常是这样:需求调查,根据用户的需求提出软件解决方案,根据这个方案进行数据库设计,设计数据库表的字段和关系。数据库设计完成之后,业务逻辑就整理清楚了,再经过简单的程序设计,就开始编码了。编码中很多是对数据库表的直接操作。业务的描述通常是这样:按下某个按钮,打开某个画面,从某个数据表中查询某种数据显示在界面上,按下某个菜单,修改数据表中某个字段……这就是从UI到DB的直接操作,不存在抽象的层次。这样的设计对于需求变化的适应程度是很有限的。
软件的开发和维护过程中经常发生需求变化,需求的变化往往处于不同的抽象层次。比如有一个设备的监控系统,管理着电动机、变压器、压缩机等多种电气设备。用户提出这样一些需求:
1.每次采集到设备的数据后,发现设备的电压大于额定电压50%的时候,自动切断设备的电源。
2.变压器的电流大于额定值的10%的时候,要在界面上显示红色的灯。
这两个需求处于不同的抽象层次,需求1是针对较为抽象的“设备”,而需求2是针对较为具体的“变压器”。这两个不同的抽象层次都应该在设计和编码中有所体现。
如果后来用户变更了需求:“当设备的电压连续一定时间大于额定电压的50%的时候,才将电源切断,否则不切电源,并且在切断电源2秒后,要重新尝试连接电源,发现电压仍然超过,就断开不再连接。”这样的需求变更就应该在“设备”这个抽象层次上进行。如果没有这个抽象层次,这个变更就比较麻烦了。
代码在项目内部,和项目之间的复用
谈到代码复用,最初的想法是设计一个完美的模块,一劳永逸的解决眼前的和长远的所有问题。其实复用也有限制,一个产品或者项目要解决特定的问题,脱离了这个具体环境,很多问题的解决方式是不同的。一般来说,我们的目的应该是写出在项目内可以复用的代码。代码在项目内部可以复用,这应该是设计者追求的目标。一旦达到这个目标,就意味着产品已经有了一个稳定的结构,进入了一个可以高效开发的阶段。复用的代码可以减少bug的发生,减少需求变更的影响。
随着客户业务的不断变化,需求难免要发生变化,这时候,要适时的对设计进行重构,以适应新的需求。原有的代码可以最大限度的复用,很多业务模块不必重新编写,推出新版本的压力就会减少很多。
代码在项目之间的复用有很多形式,可以把某个function复制粘贴到新的项目中,也可以把某些文件引入到新的项目中。这都不是复用的最佳形式。代码在项目间的复用一般以“包”作为最小单位。创建者发布一个包,使用者根据需要决定是否使用。使用的形式可以是静态的编连或者是动态调用。当包的维护者发现了bug,或者添加了新的功能,会在修改后重新发布这个包。使用者根据自己的需要决定是否升级。始终只有一个“包”在进行维护。这才是复用的最佳形式。
“复用别人的还不如我自己写一个呢。”真的吗?
我们经常有这样的体会:为了复用别人的代码,我们需要学习很多东西。查资料,看文档,读例子,甚至要读代码。有时候这个学习的时间甚至会比自己写一个相同功能的代码更长。于是,很多人在工作中不喜欢复用代码,而是倾向于自己写一个。“复用别人的还不如我自己写一个呢。”果真如此吗?
先考虑这个问题:这个“自己写一个”的时间是单纯指编码的时间,还是完整的开发时间。编码只是开发的一个阶段。自己写一个也许不难,也花不了太多时间。但是要测试、修改bug、完善文档……一系列的工作都做下来,这个时间一般都要长于复用代码的时间。
还有一个问题:自己写一个,很难做到好的复用性。下次遇到相似问题,只好再写一个。还不如现在就研究一下别的模块怎么用。
从管理的角度来说,随着项目人员的变化,这些“自己写”的模块将越来越难以维护。一些成熟的模块已经有了完善的文档,比较容易找到相关的资料,学习使用的过程也比较容易交流。开发的时候要使用能买到的最好的工具,也要复用能得到的最合适的代码。
分享到:
相关推荐
14. **可扩展性**:考虑到未来可能的变化,编写可扩展的代码,使其容易适应新的需求和功能。 15. **一致性**:在整个项目中保持一致的编码风格和实践,这样可以使代码看起来像是一个整体,提高阅读体验。 《编写可...
通过阅读《设计模式可复用面向对象软件的基础(C++)》,开发者可以进一步提升软件设计能力,编写出更优雅、可扩展和易于维护的代码。 总结来说,这本书是面向C++程序员的一份宝贵资源,它深入探讨了设计模式的理论...
它们反映了不为人知的重新设计和重新编码的成果,而这些都来自软件开发者为了设计出灵活可复用的软件而长时间进行的艰苦努力。设计模式捕获了这些解决方案,并用简洁易用的方式表达出来。 设计模式并不要求...
《设计模式:可复用面向对象软件的基础》是一本由Erich Gamma、Richard Helm等四位国际知名的软件工程师共同编写的经典之作,该书提供了面向对象软件设计中常用的模式,并通过具体的案例解释了这些模式如何帮助解决...
总结起来,“C++可复用代码——命令行控制模块”提供了构建自定义Shell程序的蓝图,利用面向对象编程和代码复用原则,使得开发者可以高效地开发出功能丰富的命令行应用。这个框架涵盖了命令解析、命令执行、错误处理...
在IT行业中,设计模式是软件工程的一个重要组成部分,它代表了在特定情境下解决...通过学习和应用设计模式,开发者能够更有效地应对复杂项目,编写出优雅、灵活的代码,这对于任何IT专业人员的事业发展都是至关重要的。
实施代码复用策略时,可能遇到的问题包括选择合适的复用机制(如库、框架、设计模式等),保持代码一致性,以及避免过度复用导致的复杂性增加。报告应提供这些挑战的解决方案和最佳实践。 总之,CMMI代码复用报告是...
这五项原则是面向对象设计的基石,它们指导我们编写更易于维护和扩展的代码。 在实际项目中,熟练运用设计模式可以帮助我们构建出更加健壮、灵活和可复用的系统。设计模式的掌握不仅仅是技术层面的提升,更是思维...
《设计模式:可复用面向对象软件的基础》是软件工程领域的一部经典著作,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位大师合著,被誉为“Gang of Four”(GoF)的经典之作。这本书详细阐述了23...
它们反映了不为人知的重新设计和重新编码的成果,而这些都来自软件开发者为了设计出灵活可复用的软件而长时间进行的艰苦努力。设计模式捕获了这些解决方案,并用简洁易用的方式表达出来。 设计模式并不要求使用...
通过学习这些模式,我们可以更好地理解和解决复杂的软件设计问题,从而编写出更加高效、易于维护的代码。后续的学习中,我们将深入探讨每个具体的设计模式,包括其适用场景、优缺点以及实际应用案例,以便在实际开发...
这些模式被广泛应用于面向对象编程中,以提高代码的可读性、可维护性和复用性。标题提及的"设计模式可复用面向对象软件的基础"是一本经典著作,通常被称为《设计模式:可复用面向对象软件的基础》或简称Gang of Four...
6. **版本控制**:介绍如何结合Git等版本控制系统,对复用代码进行版本管理和协同开发。 此外,LabVIEW的代码复用还涉及到以下方面: 7. **重用控件和指示器**:自定义控件和指示器可以标准化UI元素,确保在整个...
《编写可读代码的艺术》是一本由Dustin Boswell和Trevor Foucher共同撰写的书籍,它旨在教授程序员如何编写出易于理解的代码。该书的核心理念强调代码不仅应该能够运行,更重要的是能够让其他人在最短的时间内理解其...
在C++编程中,设计模式是一种经过验证的...它们不仅有助于提高代码的复用性和可扩展性,还能简化复杂系统的设计。在实际开发中,结合其他设计模式,如工厂模式、观察者模式等,可以构建出更加灵活和健壮的软件架构。
对于有经验的开发者,这部分代码可以作为参考资料,借鉴其设计模式和实现方法。 总之,这个压缩包包含了一个安卓应用与服务器交互的完整示例,涵盖了从数据传输格式到服务器端处理的多个关键点。无论是学习还是实际...
设计模式是解决软件设计中常见问题的经验总结,通过运用这些模式,开发者可以更有效地组织代码结构,提高代码的复用性和灵活性。 3. **架构策略**:书中还讨论了.NET开发中的架构设计,如分层架构、MVC(模型-视图-...