前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何跳过古董代码的坑

如何跳过古董代码的坑

作者头像
老齐
发布于 2020-05-15 09:20:04
发布于 2020-05-15 09:20:04
7380
举报
文章被收录于专栏:老齐教室老齐教室

作者:Isha Tripathi

翻译:老齐

与本文有关的图书推荐:《跟老齐学PythonDjango实战(第二版)》


想象下面的场景:

这是一个黑暗的暴风雨之夜。闪电每隔几分钟就会划破天空。在远处,你可以看到一大堆几年前写的代码。这些代码大部分都被作者遗忘了,甚至找不到作者。你小心翼翼地接近它,却不知道从哪里开始。你惴惴不安地决定从某一处开始,不知道你的勇敢会给团队带来什么样的灾难。

如果这个场景不适合你,那么请想象下面的场景:

在一种叫做层层叠的益智类游戏中, 每一层都在另一层上保持不稳定的平衡。只要有一个仓促的动作,整座塔就倒塌了。

这正是处理遗留代码的感觉。让我首先描述一下我所说的“遗留”代码。我指的是:

源代码来自其他人和(或)源代码来自旧版的程序。

之所以继承,通常是因为你(作为公司或开发人员)需要接手另一个公司或开发人员编写的代码,并且需要扩展和维护上述代码库。我将要在这篇文章中讨论使用遗留代码的两方面的问题:

  • 遗留代码库的常见问题
  • 通过实现交付和代码质量的平衡,有效克服这些问题

代码覆盖率

我在使用遗留系统时遇到的一个常见问题是缺少测试。即使有测试的话,也很少有单元测试,也许还有一些集成或功能级别的测试——这些测试大部分都是事后进行的,而不是对代码进行实际的保护。大多数测试或所有测试只会涉及基本逻辑的场景,并且会忽略系统中的边缘情况。

这本身可能不是一个严重的问题,但随着系统的发展和开发人员的轮换,问题就出现了。人们越来越难以追踪这些变化对系统造成的影响,因为就写了一些孤立的东西或者使用了全局变量等等,这使得代码必须高度依赖“熟悉系统”的人。

毋庸置疑,并不是每个问题都可以通过增加代码覆盖率和进行更多测试来解决,但它确实有助于消除一些风险。我们都希望确保对系统的任何更改不会影响现有功能,更广泛的测试覆盖范围恰好有助于此。此外,更多的单元测试可以确保在较低的级别捕获逻辑问题,从而更容易识别出有问题的代码。

在一个理想的世界中,任何系统都将遵循测试金字塔——大量的单元测试,一些服务测试和较少的UI/功能测试。

然而,对于你可能遇到的大多数遗留代码库,测试金字塔可能看起来像这样:

当第一次使用类似于以上图像的遗留代码库时,一个常见的误区是试图立即开始编写单元测试。虽然目的是非常可贵的,但这也意味着你在那个时候不会创造任何业务价值。对于没有看到向系统中添加功能价值的客户来说,更难证明你这样做的意义。

一个更有效的方法是,首先为你所接触的任何一段代码或你所添加的新代码编写测试。这将有助于你找到一个中间地带,这种做法叫做纸杯蛋糕模式。

注:纸杯蛋糕模式被视为反模式,因为相同数量的信息是在多个层次上测试的。然而,与传统(遗留)的代码库相比,这更适用于绿地代码库。如果你从头开始一个项目,绝对应该避免这种模式。在传统的代码库中,正是这种迫切需要但并不理想的中间地带,帮助铺平了通往理想状态的道路。

随着时间的推移,你对系统更加熟悉了,就可以继续在所有级别添加测试,并对你的项目实现一个可接受的测试金字塔。

过时的库/技术

我遇到过这样的情况:开发人员非常不愿意升级到新版本的库,因为引入的更改会造成破坏;或者由于担心破坏系统而继续使用过时的工具和技术来编写项目。

这些担心是完全正确的,绝对值得考虑。然而,人们必须记住,使用过时的工具和库会造成的副作用。这些副作用可能会在最不经意的时候累积起来,并咬伤你。旧的工具通常不再受支持,而且很难找到问题的答案。还有一个事实是,随着时间的推移,你的需求会发生变化,在某些时候,过时的工具将不再满足你的需求。

为了避免这些误区,请确保在项目中始终使用库和工具的最新版本。库的频繁更新还意味着你在升级时不会需要做出大量更改。大多数的库不会在不同版本之间(我从你的角度来看)做出重大更改,更新起来应该相当简单。即使你必须进行一些更改,更改中所花的时间也比确保整个项目的版本兼容性所花的时间更有效,因为项目中可能会有一个依赖项无法升级。

使用过时工具的必然结果是最终不得不使用极新的工具。有些工具/库仍处于测试阶段或者甚至没有一个主要版本,使用这些工具/库就要冒着不受所有平台支持的风险。我建议远离这样的库,除非你的项目有一个非常具体的利基要求。

重构

作为一名开发人员,我经常忍不住直接进入代码库,开始重新编写我认为可以改进的代码。在处理遗留代码时,第一步是阅读并理解代码,当某一部分代码理解起来非常吃力时,你会希望重构代码,让其他团队成员避免同样的痛苦。虽然你的队友会欣赏这样的行为,但它可能会损害项目的整体状态,因为它没有增加任何功能价值或业务价值。正如我之前所说的,你很难向客户证明这种做法的合理性,因为客户寄希望于你所带来的商业价值。在尝试重构这样的代码时,也很容易误入迷途。即使你决心对重构进行时间限制,你也可能会身不由己,因为你不想让自己的精力白费。

不要绝望,因为有一种方法可以处理你不太理解的代码。每当你渴望重构某段代码时,请问自己以下两个问题:

  • 这段代码是我正在开发的功能的一部分吗?
  • 这段代码当前的形式是否不够完善?

如果这两个问题的答案都是否定的,那么就不要对其进行重构。与代码覆盖一样,只重构那些在实现过程中要用的代码。其他的一切都可以添加到这个项目的“技术债务墙”。通常情况下,所谓的“墙”外观如下:

墙是一种方法,用来记录代码中的问题,或者记录你所继承的代码。技术债务墙并不是糟糕的设计决策的倾销地,我认为这是不言而喻的。它应该只应用于跟踪现有的问题,团队应该有意识地在项目过程中降低技术债务。我在一些项目中的做法是:在得到有关人员或产品所有者的批准后,优先处理迭代中的一些技术任务,以平衡所要交付的功能价值和技术价值。如果你只关注技术价值,客户会不高兴的;而如果你只关注功能价值,会不断积累技术债务,你的代码会越来越难以维护。

结论

处理别人的代码库并不总是有趣或容易的,坦率地说,有时会令人沮丧。这可能是由于人们对代码的书写方式有不同的观念,代码的原作者能力有限,或其他的一些因素。然而,这是大多数软件开发人员在他们的职业生涯中必须处理的事情。

我在处理别人的代码的实践中积累了一些有用的做法,并尝试着做了如上记录。

原文链接:https://www.womenwhocode.com/blog/dealing-with-legacy-code

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
如何破解一个Python虚拟机壳并拿走12300元ETH
之前在群里看到有人发了一个挑战,号称将 5 ETH 的私钥放在了加密的代码中,只要有人能解密就可以取走,所以我又管不住自己这双手了。
evilpan
2023/02/12
5710
如何破解一个Python虚拟机壳并拿走12300元ETH
Python写的Python解释器(四)
真正的Python字节码 现在让进入真正的Python字节码中,从一个简单的函数开始:
哒呵呵
2018/08/06
6400
一文让你完全弄懂Stegosaurus
国内关于 Stegosaurus 的介绍少之又少,一般只是单纯的工具使用的讲解之类的,并且本人在学习过程中也是遇到了很多的问题,基于此种情况下写下此文,也是为我逝去的青春时光留个念想吧~
Angel_Kitty
2018/12/19
1.2K0
简单入门python字节码混淆
我就是小菜鸡本鸡了,不是很会写东西,请各位大佬多多见谅。本文基于python2.7,因为python3并不是很懂。
ChaMd5安全团队
2019/05/07
2.4K1
你了解 Python 字节码的原理吗?
如果你曾经写过或者用过 Python,你可能已经习惯了看到 Python 源代码文件;它们的名称以.Py 结尾。你可能还见过另一种类型的文件是 .pyc 结尾的,它们就是 Python “字节码”文件。这里转载一篇文章,专门讲解 Python 字节码的相关内容,给大家看看。
崔庆才
2019/06/14
2.6K0
你了解 Python 字节码的原理吗?
【PY】Python3 字节码详解
在逆向的时候遇到过反编译 py 字节码,之前也就没咋在意,啥不会查就完事儿了,好家伙,省赛让我给遇到了,直接嘤嘤嘤😭,但还好解出来了;
sidiot
2023/08/31
3450
【PY】Python3 字节码详解
[oeasy]python0135_python_语义分析_ast_抽象语法树_abstract_syntax_tree
print("1982------Guido in cwi") print("1995------Guido in cnri") print("2000------Guido in beopen") print("2005------Guido in google") print("2012------Guido in dropbox") print("2020------Guido in microsoft")
oeasy
2023/04/16
4200
[oeasy]python0135_python_语义分析_ast_抽象语法树_abstract_syntax_tree
Python 高级教程之探索 Python code object
Code objects 是 CPython 实现的低级细节。 代码对象是 CPython 对一段可运行 Python 代码的内部表示,例如函数、模块、类体或生成器表达式。当你运行一段代码时,它会被解析并编译成一个代码对象,然后由 CPython 虚拟机 (VM) 运行。代码对象包含直接操作 VM 内部状态的指令列表,例如“将堆栈顶部的两个对象加在一起,将它们弹出,然后将结果放入堆栈”。这类似于像 C 这样的语言的工作方式:您将代码编写为人类可读的文本,该代码由编译器转换为二进制格式,然后运行二进制代码(C 的机器代码和 Python 的所谓字节码)直接由 CPU(对于 C)或由 CPython VM 的虚拟 CPU 执行。
海拥
2022/05/07
7500
Python 之父亲自优化解释器性能
2020 年 11 月 Python 之父(Guido)加入微软,按他个人的说法是自己的退休生活太无聊了。站在现在的这个时间点,一年半的时间过去了。Guido 的工作中对开发者来说感知最强的应该数 Cpython 解释器的性能优化了。
初代庄主
2022/09/22
3150
Python 之父亲自优化解释器性能
[oeasy]python0010 - python虚拟机解释执行py文件的原理
​解释运行程序 🥊回忆上次内容我们这次设置了断点设置断点的目的是更快地调试调试的目的是去除​​bug​​别害怕​​bug​​一步步地总能找到​​bug​​这就是程序员基本功调试​​debug​​我心中还是有疑问​​python3​​ 是怎么解释​​hello.py​​ 的?🤔纯文本我们的py文件是一个纯文本文件​编辑​打开我们的guido.py​如果没有就新做一个这里面是一个个的字符print("1982------Guido in cwi")print("1995------Guido in cnri
oeasy
2022/10/21
4940
[oeasy]python0010 - python虚拟机解释执行py文件的原理
python数据分析源码_python 统计分析
第一步克隆 Cpython 仓库到本地, 切换到我当前的版本, 我当前的版本号是 3.8.0a0
全栈程序员站长
2022/09/24
5870
python数据分析源码_python 统计分析
通过内置对象理解 Python(二)
在上一节的基础上,下面从一些最有趣的内容开始,这些内容构建了 Python 作为一种语言的基础,逐一对内置函数进行探讨。
老齐
2021/11/04
4050
一个关于 += 的谜题
当时看到这个问题,第一反应就是选 2。因为 tuple 是不可变对象,不支持对它的元素赋值,会报错。
AlwaysBeta
2022/02/28
3190
Python的Sequence切片下标问题
在python中, 切片是一个经常会使用到的语法, 不管是元组, 列表还是字符串, 一般语法就是:
Lin_R
2018/10/22
9870
Python dis 模块初步使用
Python 代码先被编译为字节码后,再由Python虚拟机来执行字节码, Python的字节码是一种类似汇编指令的中间语言, 一个Python语句会对应若干字节码指令,虚拟机一条一条执行字节码指令, 从而完成程序执行。 Python dis 模块支持对Python代码进行反汇编, 生成字节码指令。 先来一小段代码:
py3study
2020/01/07
1.1K0
详解Python的is操作符
is 操作符是Python语言的一个内建的操作符。它的作用在于比较两个变量是否指向了同一个对象。 与 == 的区别 class A(): def __init__(self, v): self.value = v def __eq__(self, t): return self.value == t.value a = A(3) b = A(3) print a == b print a is b 这个结果是True,False。因为我们重写了__
海纳
2018/03/02
8110
python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)
该包可以了解代码是如何转换为字节码的, dis 表示 disassemble 反汇编
Michael阿明
2022/09/21
1.4K0
python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)
【PY】Python3 字节码混淆
emmm,关于字节码混淆,最早碰到还是在校赛的时候,当时一脸懵逼,什么情况,怎么 uncompyle6 不能反编译 pyc 了,不过之后也就不了了之了,今天特地写此博文纪念 DASCTF Oct X 吉林工师魔法赛 中的一道 RE 题 —— 魔法叠加,出题人是真的阴间💩  
sidiot
2023/08/31
5260
【PY】Python3 字节码混淆
初识Python(一)
默认执行上述的hello.py文件,需要明确的指出hello.py脚本由python解释器来执行,即python hello.py。
py3study
2020/01/11
4320
笨办法学 Python3 第五版(预览)(二)
现在你将把函数与你从之前练习中了解到的变量结合起来。如你所知,变量给数据片段一个名称,这样你就可以在程序中使用它。如果你有这段代码:
ApacheCN_飞龙
2024/03/03
2540
笨办法学 Python3 第五版(预览)(二)
相关推荐
如何破解一个Python虚拟机壳并拿走12300元ETH
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档