Back to "研究遗产法典库(或承包者的生命)"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

Legacy Code

研究遗产法典库(或承包者的生命)

Wednesday, 06 November 2024

一. 导言 导言 导言 导言 导言 导言 一,导言 导言 导言 导言 导言 导言

作为一个自由职业的开发者,你需要迅速学习的技能之一 就是如何有效地在现有的代码库上工作。 幸运的是,我建造了一堆从... 破碎的系统; 这是一个有经验的开发商JOY, 但并不总是这样。

挑战 挑战

遗留系统面临重大挑战; 特别是当关键的开发商/建筑师(如果你够幸运的话) 继续前进的时候。

文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件文件

特别是在较小的公司中,这种情况往往被忽视。 一般而言,您需要4种关键类型的文件:

  1. 新建开发者指南 您如何管理此工程? 本地本地 例如,如果你需要与当前不同的框架, 特别是对于节点来说更是如此。
  2. 部署文件 当CI/CD被视为金色部署标准时 常常被忽略的是你需要知道如何手动部署系统 特别是如果你在研究一个系统, 这个系统已经存在了一段时间, 并且有很多手工步骤。
  3. 解决问题程序;当系统下降时你做什么? 你给谁打电话? 关键的东西是什么 检查? 这往往被忽视,但在生产系统中是CUCIALI。
  4. 建筑/系统设计文件系统如何运作? 关键组成部分是什么? 关键依赖性是什么? 在学习新的系统时,把它当作你的路线图。 报告高层次地概述了该系统如何发挥关键作用(特别是在更大的分布式系统中)。 这应包括使用哪些源代码储存库,使用哪些CI/CD系统,每个应用要素使用哪些数据库。 这可以包含系统每个组成部分的简单图表和完整的UML图等任何内容。 例如,在“反应应用程序”中,通常包括一个组件及其相互作用方式的图表,以及任何后端服务。 在.NET核心应用程序中,这将包括一个服务图表,以及它们如何相互作用(以及前端和其他后端系统),并可能包括 ASP.NET 视图以及它们可能使用哪些服务。

文档是我们作为开发者经常讨厌做的事情之一(这不是代码), 你们可以看到我热爱Markdown, 和美人鱼和PlantUML一样, 你可以创建一些非常好的图表和流程图, 可以包含在您的文档中。

开发商经常谈论比特罗特; 当项目的依赖性过时/直接安全风险时, 在文件方面也是如此;如果文件不及时,也无济于事。

文件的级别不同 但一般而言 修改文档中提及的代码时,您应随时更新该文档。.

本地操作系统

这往往是一个挑战;特别是如果该系统已经存在一段时间的话。 您需要知道什么版本的节点 /. NET 等, 数据库的哪个版本, 框架的哪个版本等 。 这往往被忽视,但对于迅速起立和运行来说,却具有催化作用。

我经常看到开发商说这在云层系统和分布广泛的应用软件的时代并不相关, 但我不同意;你必须有能力在当地运行这个系统, 以便快速有效地调试问题。

  1. 分析 - 这似乎已经成为一个“ 先进开发者” 的技能, 但关键是能够描述您的代码, 以了解瓶颈所在 。 在一个遗留的系统中尤其如此,在这个系统中,你可能没有奢侈的奢侈条件,无法从头重写这个系统。 类似工具的工具 多跟踪dot 记忆在这里是宝贵的。 特别是在 ASP.NET 应用程序中;最大的问题通常是系统中的“渗漏”;内存泄漏、连接泄漏等。 当您的应用程序似乎会运行 FFFE 一点点时, 你突然发现它正在崩溃/ 耗尽服务器上的所有内存 。
  2. 在调试器中查找问题- 是否喜欢 Response.Write 在经典ASP结束。 对于一个相当复杂的应用程序(尤其是那些你没有写的应用程序)来说,关键是要“通过”代码。 从开始到提供服务期间,根据一项请求,查明可能发生的情况、可能不会遇到的例外情况等等。
  3. 日志 - 经常被忽略( 仅靠堆叠顶端的 ASP. NET 核心过滤器是不够的) 。 回到我的 上一个职位,伐木是LOCLEY代码工作的关键部分。 记住,您可以使用客户记录类型(例如使用 伐木源发电机ASP.NET核心部分。 然后您可以指定哪些事件类型应该记录,哪些事件不应该记录。 这对于一个遗留制度至关重要,因为在这个制度下,你可能没有奢侈的奢侈条件,无法从头重写这个制度。 对于应用程序 Insight, 您可能想要用户旅行和其他特性; 但是要注意 这么快就变得很贵了 如果使用 LogInformation 对每一项请求都适用。 您可能想要使用自定义的遥测处理器来过滤您不想登录的请求 。
    • 测试 - 我经常看到开发商“在预测试中测试”或认为单位测试在测试中检查就足够了。 使用Resharper / NCrunch这样的工具来自动进行单位测试, 两者都有很多价值; 但是记住单位测试只是这样; 它们测试代码的“ 单位 ” 。 您需要保持能见度 在系统如何实际运行 与其他组件协调。 这就是整合测试的来处;它们测试整个系统是如何运行的。 您可以使用类似工具的工具 分光花 以人文可读格式写出这些测试。 再一次,在遗留的系统中至关重要,因为在这个系统中,你可能没有奢侈的奢侈条件,无法从头重写这个系统。

在每一个项目中,我工作的第一步就是让系统(或其中的一大部分)在当地运行。 通过看到代码,运行代码,调试代码 你可以感觉到系统是如何运作的。

代码库

在每一个系统中,这是你的 真相来源来源无论医生怎么说, 其他人怎么说应该如何工作, 这就是医生如何工作。

导航遗产代码库

这往往具有挑战性 就像在没有路线图的新城市里寻找你的方式 幸运的是,在应用程序中,您有一个切入点(页面加载/前端 API 呼叫等) 选择一个点然后从那里开始。

使用任何你需要与它互动的东西, 无论是邮递员,骑士的 HttpClient 或甚至网页。 钩在你的调试器, 打电话和跟踪它通过。 系统每个部分都进行冲洗和重复。

重构

通常离开这个 直到你了解这个系统。 它总是诱使"把它扔掉,重新开始" 但抵制这种诱惑。 特别是运行系统 它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作,它的工作 重建/甚至重新构筑一个系统是HUGE的风险。 是的,这是有趣的,但对于每一行代码 你改变你的风险 引入新的螺旋刺激虫。

与其它一切(特别是签订合同时)一样,您需要证明您在系统上所从事的工作是合理的。 要么这一理由需要侧重于以下一个理由:

  1. 业绩 业绩业绩 业绩业绩 - 系统缓慢,需要加快速度(再次要小心,你发现缓慢的可能是系统的设计如何运作)。 使一个部分吸烟速度快,可能会给系统带来更多问题。 您是否将“ 杀死” 数据库服务器, 如果您提出太多请求, 您是否有一个机制来避免串联异常?
  2. 安全安全安全安全安全安全安全安全 - 系统不安全,需要保障安全。 这是一个棘手的问题,特别是在遗留制度中。 使用比特罗特,你可能会发现这个系统 正在使用旧版本的图书馆, 这些图书馆已经知道安全问题。 这很好地说明了工作的理由;然而,要了解你可能需要重新构思一个系统LOT来更新它;再次导致“新虫”问题。
  3. 可维持性 - 系统难以维持,需要更加容易维持。 一般来说,这已成为许多工作;代码库目前的使用寿命是否证明这样做是正当的? 如果你花更多时间做这些改变 来改善可维护性 超过你为客户省下的钱 那就不值得了 (又改了代码 = 新虫子)
  4. 用户经验 - 我一般优先考虑这些问题。 a 用于 a 用户用户 不管你的代码是否更好1%, 都无关紧要; 他们就是最终为您的工作支付报酬的人。 如果你能让他们的体验 比一般情况下值得的要好 但是,请注意,这可能是一个变化的“滑坡斜坡”;你可能会发现,你正在改变一个系统的LOT,为用户做一个小的改变。

《遗产制度工作业务》

这一点往往被忽视;特别是开发商忽视了这一点。 你需要能够证明你在系统上的工作是正当的 这在订约环境中尤为如此,在这种环境下,你按小时支付工资。 归根结底 这不是你的密码 也不是你的钱 你为何要改变 往往比改变本身更重要

我作为承包商工作了十多年了 这已经不是简单易行了 作为承包商 你每个小时的时间都是客户的“成本” 您需要为系统添加移动值, 而不是成本 。 如果你不是,你很快会 寻找新的合同。

作为开发商,我们往往都是些讨厌的生意人 我们每次都专注于“完美” 在现实中,你不需要让一个系统“完美”(我认为没有这样的东西); 你只需要给客户提供价值。

在更长期的接触方面,本《公约》确保 新建新 代码是可以维持的,而且运行具有成本效益。 在遗留系统中,这是MUCH HARDER。 你常常不得不在沼泽里漫步, 急切地希望当你学习到这个系统时, 你无法提供很多价值。 I'm not making any changes 您认为 I'm just learning the system. 这是一个谬误; 你正在学习这个系统来使它更好。 你正在学习这个系统来提高它的效率 你正在学习这个系统 使它更能维持 如果客户不能接受这一步骤;那么,你需要非常小心地了解如何传达这一信息(或寻找新的合同)。

人民人民

经常被忽略, 很多时候你作为承包商被带进来 是因为某个关键人物离开了(不要卷入政治; 这不关你的事)。 您需要能够与当地人民合作,以实现项目的目标。 在一份合同中,你一般会把约定的条件写明(在我目前的合同中,这是“提高可靠性和降低运行成本”); 专注于这一点。 如果你不知道这意味着什么 那么ASK。

记住你的直接接触对象是谁,特别是在头几个月。 让他们随时了解(你可能没有新的功能可以炫耀, 我通常每周/两周都会发电子邮件给直接联系人; 这是让他们了解你在做什么和发现什么的好办法。

请记住,这个人将批准你的发票;在发票上不应有任何意外。 一旦你开始定期检查代码,这不是什么问题;你对你的所作所为及其影响都有记录。 在那之前,你应当通知他们。 他们需要知道你做了什么 他们为什么要付钱给你

可靠性

再说一遍,回到遗留代码;如果你改变一下一般的代码,你就需要部署它。即使我们中最好的人也会不时搞砸,特别是在遗留代码系统中,也会有一些东西 你无法知道 当你们部署时。 这又回到了记录 - 如果你有一个中转服务器, 它会记录一个 LOT (但被短期保留), 然后当您部署到这个服务器时, 您可以收集更多关于失败的信息 。

无论你有多好 你做了多少局部测试 我们都是人类 这是“不要在星期五部署”规则的关键部分; 期待部署在系统上引起新问题。 准备好工作,直到解决为止 如果您不知道为何失败, 增加更多测试来复制问题, 并增加记录, 以确保您在未来发现类似问题。

特别是对于生产系统,您的中转系统可能不是1:1(特别是在涉及负荷的情况下),例如: k6 k6 能够帮助您模拟负载(如果您可以进行前面提到的正确剖析,则更适合本地) 。

部署部署

在CI/CD的热潮中经常被忽略的是这些原因的原因。 很简单 你会搞砸的 拥有非常快速高效的部署系统的方法 意味着当您真的打破了它,您也可以 更快地修复它。 如果你的CI代码审查系统 意味着需要两天时间 才能合并公关 那么这是最快的速度 如果您的 CD 系统意味着您取消了运行系统; 习惯了 长夜 。

确定和部署守则的有效机制对于有效发展管道至关重要。 如果需要比在代码中找到和实施修复需要更长的时间来部署修复,那么你更不可能修复东西。

“ 固定遗产应用程序”

我引用了这一点,因为这是一个问题;对于遗留应用(特别是当大规模重整工作超出界限时),有两种主要的方法。

  • 正在运行的补丁

这是简单地确定现有代码的过程;再次确保您彻底测试,并具备恢复/迅速重新部署任何修正的程序。 我不会说谎 这种类型的发展 很少是FUN 因为你仍然可能 流过沼泽 现有的代码库。 然而,这在很多情况下是必需的邪恶。

和往常一样,您应该确保您有某种测试形式来解密当前代码; 最好它也应该测试是否失败, 以便解决您在做出修正前想要解决的问题 。 . 他们IDYLL 这样做是进行单位测试, 密切针对您需要修正的代码领域, 但对于大型分布式系统来说, 这往往不属于工作范围 。

我通常使用一种测试系统 以这种优先顺序排列:

  1. 单位测试 - 也比较喜欢这些, 因为您可以针对这些测试来练习您正在使用的代码 。 然而,在遗留的系统中,这些系统往往不存在,而且极难改造(例如,在一个有许多外部电话的系统里,/ 其构建方式混乱;不使用DI等)。
  2. 集成测试 - 这是一个超载的术语, 因为它可以覆盖单位测试, 通过多层代码( 最好避免这些代码) 使用优异的类似代码 。 核查核查 甚至到试验。 一般而言,你想对整个系统进行测试,但要意识到这些测试可能缓慢和易碎。 使用校验对于遗留的系统来说 通常是一个很好的方法, 因为至少您可以“ 校验” 您没有打破系统的 API 表面 。
  3. 手动测试 - 每一个开发者都应该尝试操作手动测试 来进行任何代码检查 。 这只是确保你所期望的“用户”(这可以是实际的用户或与您的代码互动的系统的另一组成部分)能够看到他们实际看到的是什么。 这可以像在本地运行系统、检查页面输出一样简单,也可以像在中继服务器上运行全套测试一样复杂。
  • 洋葱皮 对于研究遗留系统 你一般不会奢侈 完全重整工作。 这就是我使用“洋葱皮剥皮”方法的地方。

为使您能够升级系统部件,您可以识别能够从现有单体中分离成微服务(对于“微”的某些值)的部件。 这可以成为在没有全面重组风险的情况下开始使系统现代化的伟大途径。 常见的例子可能是将API的终点分成使用更新内容的新项目。 然而,DRY的恐怖可以在这里发挥作用。 结构不完善的解决方案往往有许多“帮助者”或“服务”组成部分,这些组成部分实际上应该属于不同的项目(甚至是用于更全球再利用的微粒包)。

我将在未来的一篇文章中进一步阐述这个方法,因为这是我如何在遗留系统上工作的一个关键因素,而且对于许多开发者来说并不明显。

领薪

现在,我们有这一切 的方式,那里有 棘手的支付问题。 我有一条通则:

任何付款问题,我想继续处理

如果他们迟付款; 取决于您的合同,但在30天内在东部,但一般接近7; 这是一个坏兆头。 如果你的发票(nickle-and-meing)上有夸夸其谈,

不要乱来,如果你完成了你的工作,你需要及时得到报酬。 不管你有多享受 如果一个坏客户能利用你 他们也会利用你 这不值得

诚实一点,只收你实际工作的时间; 确保清楚你做了什么,为什么你这样做。

我领导了开发者团队,我是一个开发者; 我是一个承包商,我是一个客户。 我从各方面都见过,我可以告诉你 如果你没有按时领到工资,那你就得继续前进了。 如果你有一个没有交货的承包商(或FTE),那么你就必须迅速解决这个问题。 每个人都有个人挣扎, 但特别是在合同环境中......你需要提供价值......或者不收费的时间,当你不是。

至于利率,你会发现你的水平; 个人来说,我对责任更重(或看起来不好玩)的项目收费更多。 我在学习新技术的项目 或初创项目 费用都比较低 我工作的时间也少了,但我保持我的利率稳定。 但不要接受低球率; 你是一个专业的, 你应该得到这样的报酬。

在结论结论中

就是这样。 我今天和明天都下班去参加我奶奶的葬礼 坦率地说,我有点惊慌 我有一个HUGE的遗留系统需要学习 所以我想我会呕吐

logo

©2024 Scott Galloway