防止代码变质的思考与方法

yuruky 2012-12-29 09:55:22
1、软件长期运营存在什么问题
一个大规模的客户端软件的生命周期中,我们可以把它分为两个比较粗的时期。一个是前期的搭建软件的时期,即从无到有的时期;第二个是搭建完成之后, 进入的一个稳定的运营时期。第二个时期才是最关键的,在这个时期我们会持续的迭加需求,持续的优化功能,而且第二个时期也是代码在慢慢变质的时期。
在这个时期,你可能会发现:我们的软件慢慢出现模块耦合严重,牵一发而动全身;每个版本都会涌现出老功能的BUG,你没动过的模块也会出BUG;或者改了一个小问题了,带出来很多其他问题;缺乏扩展性,往老模块加新功能非常痛苦;程序的崩溃率越来越高;新员工接手老模块经常不能理解原来的设计思想而改坏;移植一个DLL到另一个软件时,发现必须连带也移植十几个DLL。本文将分享对于这些问题的思考与方法。
2. 软件的积木模型
一个运营型的客户端软件,做出来就是为了长期运营,需要不断的迭加功能。而不是做出来,两三年就重写一次。那么这样一个软件就像堆积木一样。一个软 件刚开始写了两千行代码,感觉设计得非常好,模块化扩展性都非常好,性能也非常快,都能很好的面向运营。写了两三年之后,就会出现像这种积木一样的结构, 很容易崩塌。所谓重构,形象的说,可以看做是某个积木不稳定,要往里塞一塞。那么整个开发过程,就是一个不断迭代、不断优化、不断重构的过程。对于我们这个积木模形,有什么办法不让一些木条跑出来,这也是我们需要想的思路。我们是不是可以先围四面墙,然后在墙里面再去塔积木?

3. 导致代码变质的两大因素
团队中总是会存在这样那样的问题,这些问题最终总是影响到我们的代码朝着不良的方向发展。对于这些因素,我可以将它们抽象为两大类。一类是人的因素:比如架构设计不合理,需求没考虑清楚,项目进度压力,沟通问题,缺少文档、培训,等等。另一类是时间的因素:比如人员的变动,需求的长期迭加和变更, 等等。人的因素是由于人本身的素质或疏忽导致,时间因素是由于时间的长期推进导致,即使人的素质很高也必然会出现时间因素的问题。
4. 代码变乱的微观原因
在上述两大类因素的长期作用下,最终会导致代码越来越乱。如果从微观的角度来剖析,这跟依赖有着很大的关系。代码的变乱,根本原因就是由于太多不良依赖或者模块失去单一性所致。我们来看一下依赖是如何产生的。
1). 依赖的方式
如下图所示,如果组件A依赖于B,B依赖于C,A也是隐含的依赖于C的。组件A不能单独使用,必须同B和C一起使用。在现实的代码中,可能存在着非常长的依赖链。

依赖的方式也可能是多种多样的,单向依赖、双向依赖、环状依赖或者一个依赖于多个。下图也是一些示例,现实的代码中可能是由各种依赖方式组成的非常复杂的网状结构。

2). 依赖的变化
在两大类因素的作用下,依赖会发生变化。最常见的变化应该是依赖的箭头越来越多,网状结构变得越来越复杂。如果没有增加新的组件,下图中左边的图往 往会变成右边的图。起初设计好的很好的代码,可能是左边的样子,模块具有很好的独立性和可移植性。随着时间、需求、人的变化,很可能由开发人员很随意的一 行代码,就变成了右边的图,一条红线就出来了。两个模块变成相互依赖,上面那个模块就不再有独立性和可移值性。
我们的代码从设计之初到现在,中间经过了几年的时间,代码变得越来越乱很大的原因是因为这种红线的持续出现。本来有很多独立性很好的模块,变成了错综复杂的网状结构。

前面是没有引入新组件的情况,如果引入了新组件,必然会引入新的引赖,那么就要好好的去界定,引入的新组件是属于哪个层面的。像下面第一个图,新引入的组件依赖于原来两个组件是在最上层,第二个图新引入的组件是在中间层,第三个图新引入的组件被另外两个组件依赖在最底层。

引入新组件,其实应该做好充份的考虑,而不是让开发人员随意的引入。需要充份思考引入的新组件应该放在哪一层面才是最合理的,才有利于以后的扩展和移植。
可能读者会遇到这种情况,一个功能编译没有问题,测试也没有问题,发布后一两年也没有问题。当我们要把这个功能移植出来的时候,才发现问题大了。你想移植一个组件到另一个软件时,必须连带也移植十几个组件。

...全文
260 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
freeman_zxt 2013-01-10
  • 打赏
  • 举报
回复
说点个人体会, 在开发中,应重点考虑两点,一是可维护性,二是可读性, 这二点相辅相成, 用一个现在比较时髦的词,就是“可持续发展”。 一个函数三千行,那还有什么可读性,可维护性,别说让别人改,就是让原来写代码的人去改,都会出问题。
freeman_zxt 2013-01-10
  • 打赏
  • 举报
回复
每次修改BUG,每次添加新功能,都是一次很好的重构机会。 不能等到模块耦合严重了,缺乏扩展性了,再考虑重构,那时已经晚了。
yddd2011 2013-01-10
  • 打赏
  • 举报
回复
项目负责人垃圾,你想改都没有机会,多一事不如少一事。
赵4老师 2013-01-10
  • 打赏
  • 举报
回复
个人意见:重点不是函数有多少行;而是变量和函数命名与其对应的意义是否一目了然。
xiaoxiao8310 2013-01-09
  • 打赏
  • 举报
回复
我最近接手一个功能,一个函数快到三千行,直接崩溃。。。至于让我小改动啥,那真是步步谨慎,要不直接搞死。
jimette 2013-01-02
  • 打赏
  • 举报
回复
melos 2012-12-30
  • 打赏
  • 举报
回复
很好,很有同感
内容概要:本文围绕“阶梯碳下考虑P2G-CCS与供需灵活响应的IES优化调度”展开,基于Matlab平台构建综合能源系统(IES)在阶梯式碳交易机制下的优化调度模型。研究深度融合电制气(P2G)与碳捕集、利用与封存(CCS)技术,结合需求侧灵活响应机制,旨在提升系统的低碳运行能力与经济性。通过建立多能流耦合的优化模型,协调电力、天然气、热力等多种能源形式的协同调度,有效降低系统碳排放强度,并借助YALIMIP工具包调用求解器进行高效求解。文档提供了完整的代码实现、模型构建流程与结果分析方法,涵盖从问题建模到仿真实现的全过程,具备较强的可复现性与科研参考价值。; 适合人群:具备电力系统、能源系统或优化建模相关背景的研究生、高校教师及工程技术人员,尤其适合从事综合能源系统、碳减排策略、P2G与CCS技术集成研究的专业人员,需熟练掌握Matlab编程与基本的数学规划知识。; 使用场景及目标:①用于研究阶梯式碳交易政策下综合能源系统的低碳经济调度策略;②支撑P2G-CCS技术与需求响应机制在IES中的仿真集成与性能评估;③作为撰写高水平学术论文(如EI/SCI收录)的技术基础与复现资源,推动碳中和背景下能源系统优化方向的创新研究。; 阅读建议:建议结合百度网盘提供的完整代码与资料包,按照模块逐步调试程序,重点理解目标函数的设计逻辑、碳交易成本的建模方式、约束条件的数学表达及求解器的配置方法,同时关注多能耦合设备的建模细节,配合公众号“荔枝科研社”获取持续的技术支持与案例拓展。
内容概要:本文系统研究了基于卷积神经网络(CNN)与支持向量机(SVM)融合的CNN-SVM混合模型在数据分类预测中的应用,尤其聚焦于工业故障识别领域。通过Matlab平台实现,该方法首先利用CNN强大的多层次特征提取能力对原始输入数据进行深度特征学习,自动捕获关键局部模式与空间结构信息,随后将提取的高层特征作为输入传递至SVM分类器,借助SVM在高维空间中小样本条件下卓越的分类性能与泛化能力完成最终判别任务。文中详尽阐述了模型的整体架构设计、网络参数配置、训练优化流程及特征迁移机制,充分结合了深度学习在特征表达上的优势与传统机器学习在分类决策上的稳健性。实验部分通过实际故障数据集验证了该混合模型相较于单一CNN或SVM模型在分类准确率、鲁棒性和抗过拟合能力方面的显著提升,证明了其在复杂故障诊断任务中的有效性与先进性; 适合人群:具备一定机器学习与深度学习理论基础,熟悉Matlab编程环境,从事故障诊断、模式识别、智能制造、电力系统监控或工业数据分析等相关领域的研究生、科研人员及工程技术开发者; 使用场景及目标:① 应用于旋转机械、电力设备、航空航天等领域的多类别故障识别与状态监测;② 掌握深度特征提取与传统分类器融合的技术路径,提升小样本、高噪声环境下数据分类的精度与可靠性;③ 为撰写高水平学术论文、开展科研项目或工程实践提供可复现的算法框架与完整代码支持; 阅读建议:读者应深入理解CNN与SVM的协同工作机制,重点分析特征提取层与分类层之间的接口设计,建议动手运行并调试所提供的Matlab代码,尝试在不同数据集上进行迁移实验与参数调优,以全面掌握该混合模型的应用技巧与优化策略。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧