如何在遗留代码基础上开发

       对于大多数开发者来说,在遗留代码基础上开发是日常工作的一部分,毕竟从头开始创建全新系统的机会不是很多。架构师、《漫谈设计模式》作者刘济华结合自身的实际经历分享了如何在遗留代码基础上开发的经验。

  刘济华首先指出,大多数系统是构建在之前的遗留系统之上的,在开始,很难把遗留系统直接丢弃,特别是一些业务逻辑非常复杂的金融电信系统。 这些代码往往有如下特点:

  • 旧的编程语言开发低效。
  • 代码冗繁,质量差。
  • 添加新的功能和修改错误(Bugs)的周期时间长而痛苦。
  • 这些代码没有单元测试,甚至没有功能测试、冒烟测试、回归测试。
  • 无法交接这些代码,因为写代码的这些人很多已经离职。
  • 维护这些代码代价高,大家心惊肉跳,特别是系统遇见特殊情况(节假日,高峰访问期等),无法安宁。

  但是这些代码能够完成当时的功能,直接抛弃这些代码,重新开发将会耗费很大的资源,且不一定成功,如果新的需求不断变化,往往没有时间来重新开发这些代码。而这些遗留代码的功能没有完善的文档说明,甚至没有。 在此现状下,如何改善这些代码,将是考验程序员和一个团队的智慧。

  接着,刘济华分析了对于遗留代码取舍的亲身经历。

       具有性能瓶颈的遗留系统——曾经遇到过一个应用服务,是C语言写的,周围其他系统都是采用 Java 开发,与此系统的交互都是采用非标准的协议完成,而且此系统处于比较核心的位置,但是维护非常复杂,不稳定,访问压力大是经常宕机,无法水平扩展,只能提高硬件设备水平等方式考虑。

  在原有协议基础上开发,使其具有水平扩展能力,代价和开发一套标准协议的实现没有任何区别,往往会带了协议不够完善所产生的问题。于是,我们为其开发新的标准协议,WS,MQ 等等,然后在标准协议上负载均衡实施水平扩展,非常方便。

  随着后来的发展,此遗留代码也慢慢被新开发系统取代,期间经历了新系统和旧系统同时存在,此时新系统未完全具有旧系统的全部功能,这部分功能还是使用旧系统完成,只不过在原有均衡负载层多了层查找和分配的,后来到旧系统完全取代。此过渡还算平顺。

       功能性改造型系统——大多数就是这种系统,保留的话,代码极其复杂,维护麻烦,丢弃的话,无法一夜之间写出新的系统。曾经接手了一个开发失败的项目,包括代码和文档都未完善,如果重新来过,终究不划算,后来在此系统上进行改造,特别是花了大量时间写单元测试,保证代码测试覆盖率极高,这样一边熟悉代码,一边重构代码,系统的健壮性发生根本改变,前提是有时间。这只是特例。很多时候遇见的系统,同样测试代码很少,在添加新的功能和修复错误(Bugs)时,为这些能够接触到的代码完善测试,新代码必须测试覆盖率必须很高,经过 4 个月,,此系统代码覆盖率已经达到 50% 以上。以后的迭代开发越来越快。

  那么如何在在遗留代码上编程呢?刘济华觉得首先要找到代码修改点:

       遗留系统代码往往测试少,或者没有,导致软件开发者对软件发布没有信心。但是为所有的遗留代码写单元测试,初始代价非常高,在添加一个很小的功能时,并没有时间大动干戈。

  如何找切入点呢?刘济华总结了几种情况:

       修改一处代码即可,这个时候非常简单,修改代码处即为切入点,找到这处修改即可,为此处代码写完善的单元测试代码,特别是对于输入条件和测试条件尽量能够完整测试

       修改多处代码,位置分散,并且修改代码如果有多种方案,我们找出最少修改代码的地方,而不是最佳的修改方式,很多时候,此时最佳的代码修改会修改很多代码,导致测试代码无法一下子完善,另外,此时认为的最佳方案随着时间的推移,或许又是糟糕的代码,所以没有必要花费更多的精力在上面,当然也可以选择比较中庸的方式。

  在修改时需要一些技巧,其中包括:

  • 找测试方便、改动较小的方式来修改遗留代码。
  • 重构在一个类中那些重复的方法,并且保证其健壮性。
为依赖的具体类提取新的接口,并使用注入依赖技术,使得测试更加容易,不管是使用 Mock tool 还是自己编写 Mock 对象,都会非常容易测试。
  • 尽量使测试的范围缩小在受修改影响的类中,对类中的改动进行全面测试。保证每处修改完全测试,保证测试类减少。
  • 类之间交互的代码重构,如果这些交互仅在修改的代码之中,只要保证修改的代码完全测试即可。而对于那些可能影响此时其他不需要进行修改代码的类,可以先放下,为其创建新的方法,在此次修改和以后修改中,使用和重构新的方法。对于老的方法,等到以后代码覆盖率提高,能够覆盖所有此类交互方法的代码时,重构此方法,这是你会发现,修改很简单,并且如果修改错误,或者不能处理极端的逻辑,也会和容易找出问题所在。
  • 努力汲取业务逻辑知识
  • 《修改代码的艺术》(Michael Feathers 著)建议找到切入点(Inflection Point),往往我们找的点很多,每一次修改都可能不一样,为此花很多代价找寻,还不如直接进入修改,找出最佳的修改方式避免代码过度重构和修改,减少影响,这才是有有实践价值和有意义的。

  如何保证质量呢?刘济华建议:

  • 尽可能让一切自动化——单元测试自动化是最基本要求,尽可能让一切测试变得自动化,不管是单元测试,还是功能测试,还是压力测试、冒烟测试、回归测试。发布自动化也是非常重要的。
  • 为项目加入冒烟测试和回归测试。逐渐保证代码质量。
  • 坚持可控变化、逐渐渗透的原则,保持系统稳步的朝健壮的方向进行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值