昨天需要项目时如何使用遗留代码滑行

你好 我叫Ivan Melnichuk,我是乌克兰IT公司开发部主管。 在出版物中,我想分享我个人的专业方法,以解决项目的快速发展过程中的遗留代码问题,并讲述在“需要昨天移交功能”的情况下我们团队所采用的技术。

我们处理这个项目


为了传达对旧工作的准确,周到和艰苦的工作,我将举一副扑克牌来做个比喻。

图片

这就是旧代码的样子。 如果我们决定从该建筑物中移除或更换至少一张卡片,则可能会导致整个房屋不堪重负,并将其残骸与地面齐平。

旧版的行为大致相同。 因此,承担现代化并将项目“呼吸第二生命”的任务的程序员的工作在某种程度上应该是珠宝。 大多数程序员试图避免并且通常“跳出话题”的技术债务。 甚至编写了一个流行的游行,引述了陷入传统情况的程序员必须听到的最常见的报价:

  1. 我们创建了一个“简单”站点,现在您想获得一个新的“小玩意”,并且由于存在遗留问题,我们需要重写所有这些内容。
  2. 没有人知道这是如何工作的..
  3. 要添加一个模块,您需要检查整个站点-只有这样我们才能了解它可以在什么地方以及从哪里出来...
  4. 无论如何我都不会去那里,那里的一切已经很糟糕了...

但是编程经验表明,遗留的生命存在。 编程没有问题。 只有任务需要解决。 在制定“克服继承代码”的行动计划之前,您需要了解整个项目的不良状况。 在实践过程中,他确定了项目问题的六个阶段:

  1. 没有技术文件。 问题的最低阈值,因为您可以测试并初步猜测这应该如何工作。
  2. 没有商业文件。 如果缺少所有文档(技术文档和业务文档),就会不由自主地出现“似乎我们陷入了历史”的感觉。 确实,即使是一家企业也不记得它应该如何工作,这意味着至少,该团队对预期结果不了解。
  3. 没有人设计这个。 如果除了缺乏文档之外,没有其他开发人员可以解释该项目的工作方式,那么它已经散发出来了。
  4. 我们不知道用户最终应该得到什么。 当问题仅在后端出现时是一回事,但是如果我们仍然完全不知道应该在前端显示什么,那么这已经接近“病人比活着更可能死了”的状态。
  5. 每个函数有200多种用法,它们称为getA 。 第五个难度级别:进入传统时,您会看到功能A和200的用法,而且没人知道它为什么是...
  6. 没有愿意/可以发展的程序员。 暂无评论。

了解业务


企业数钱。 企业不希望仅仅在重做已经起作用的方面花费额外的财务资源。 企业永远不会接受这样的想法:“我会以一种新的方式来做,因为我不喜欢它。” 因此,始终提供更多。

通常,开发人员将业务推向无用的想法。 在这种情况下,有单独的“黄金报价基金”。

  • 我们正在招聘一个新团队来进行高质量的代码“锯切”。 也就是说,我们需要一个专家团队,他们将与现有团队并行进行项目。 结果不会有所不同,但业务应该已经包含两个项目。
  • 我们不再添加功能,现在只能重构! 您正式向企业宣告:绝对禁忌使用功能,只能在后台“按顺序放置”。 您非正式地说,您不会对项目进行大规模的改进和改进,只能在本地“修复”它们。
  • 我已经有了WP所需的一切,我只需要迁移数据库。 这是初学者的“症状”。 六月最喜欢的歌曲:这是一个如此简单的网站,仅能播放一两个小时...

要与企业就过时的代码的轮回进行谈判(在新的获利功能的作用下使用),有必要从打开新业务视野的角度出发。 但是,在进行谈判之前,必须先回答以下问题:

  1. 公司准备好成长了吗? 您需要了解:企业是否有提高财务标准的要求,或者只是需要服务才能更有效地工作。
  2. 原型阶段? 通常,一家企业订购一个简单的原型,希望在产品相关时用它“探测”市场。 并且只有当他开始赚钱时,企业才准备将功能开发为更高级和完整的项目。
  3. 开发完成,现在仅支持吗? 了解所有任务很重要。
  4. 我们眼中有足够的火吗,它不会熄灭吗? 该项目应该激励而不是激励。 您的团队要参与Legacy的轮回非常重要,否则人们将逐渐分散到他们感兴趣的项目中。
  5. 有建筑师吗? 这是最重要的问题-您是否有一个人可以制定正确的架构并已经开始编写好的代码。 如果没有架构师,甚至尝试开始也没有任何意义。 否则,您将在一周内成为创造问题遗产的人。

当您将创意推销给企业时,专注于“新,创建,添加”消息……企业对系列产品的反应非常好:“我们将为您提供一项新功能,而X项目将更快……”和“要增加转换率,请添加新的... ”

P-规划


为了快速有效地处理技术债务,您需要一个计划。

1. 定义我们将寄生的任务。 为什么要寄生? 这经常发生:我们出售了一项功能,因此部分地意味着重构。

2. 定义高级要求。 为了草拟正确的文档,有必要注册明确的“高标准”业务请求。

3. 定义系统的主要模块,强加模块。 在开始重构之前,您需要了解系统的主要模块:可以交互的位置,方式,内容以及内容,以及将代码划分为多个部分。

4. 整合的定义。 在创建特定模块时,我们需要事先考虑将其安装在相邻旧版中的能力。

5. 团队定义。 重构领域中的一个不是战士。 团队是取得成功的一个非常重要的因素。 积极进取,团队合作精神以及必须参加的过程中参与者之间的出色互动。

6. 我们将如何测试? 如果您要进行高质量的项目,则需要提前考虑和进行产品测试。

除上述内容外,确定所需的最终结果,制定扩展计划并记录项目瓶颈也很重要。 例如,在代码缩放的情况下,重要的是要了解在高负载情况下可能在哪里出现问题(它可以是数据库,繁重的查询,或网格或某些其他可能“掉线”的中间链接)。

确定项目的边界,存在旧代码的地方以及将出现新水平的“杰作”的地方同样重要。 您还应该考虑采用微服务或DDD的方法,或者也许您需要更多的“纳米技术”。

忍者传承技巧


在“准备工作”之后,我们介绍了有助于节省技术债务的技术。 对于Legacy中的所有疾病,没有通用的配方和灵丹妙药,但是在高负荷项目的工作过程中,我列出了可以准备真正“美味”代码的配料清单。

1. 不要重新发明轮子。 对我而言,这是编写代码的主要生活技巧。 一切都是在您之前发明的,不要诉诸于手鼓和其他实验来解决遗留代码的问题。

2. 该代码为标准代码。 没有统一的标准,每个开发人员将以自己的方式编写。 “作者的风格”将导致混乱并增加更多的代码垃圾。

3. 代码审查。 不仅存在一种代码标准。 团队也有责任对其进行检查。 否则,一切都会恢复正常,即恢复到旧代码的级别。

4. 静态代码分析器,PHP混乱检测器等(而不是一千本书) 。 将需要这些和其他自动技术来加快过程,尤其是使用相同的审阅代码时。

5. 我们尝试微服务。 另外,也可能有模块或库。 为什么选择微服务? 它们的优点是尽可能地隔离逻辑并将其限制为特定的API。 后者的优势在于,与“可修复的代码中的适配器”相比,API是更加单一的实体。 但是,API具有额外网络成本形式的一个缺点。

6. 数据库体系结构,数据源。 我认为这是任何传统的第一个瓶颈。 但是每个人都可以按自己的意愿进行设计,甚至在SQL中,您也可以发现没有重点的缺陷。 以下是使用新数据库的一些技巧:

  • 没事,渴求一切。 如果要将旧的不正确的数据结构更改为新的数据格式(更快,更高效),可以采用两种方法。 首先是建立一个新的基础,完全删除旧的基础,不管发生什么。 第二种-如果是硬性遗产,则并行引入新格式。 形象地说,在老树旁种一棵新树。 为什么第二种方式是合理且更有希望的呢? 因为所有新功能都将高效运行,并且如果在部署过程中或在集成阶段出现问题,则只需回滚代码,而无需回滚所有复杂的数据库迁移。
  • 将以正确的结构创建一个新的数据库。 在创建新资源时,控制我们编写新结构的位置非常重要。 同时,有必要为旧结构提供支持,因为要完全摆脱旧结构是不切实际的。 也就是说,我们将继续编写新材料,同时我们支持旧模板,将所有新内容都转换为新模板,从而使旧模板也可以工作-就像旧方法一样,但是支持新结构。
  • 我们控制整个记录。 我们不会错过关注领域的细节,以保证数据库的支持。

7. 但是SQL? 如果从体系结构的角度来看,您可以使用实体进行操作-进行操作。 确定和有限的概念将帮助您避免创建不必要的重复关系。

8. 装饰器,适配器,选择器...这些模式是将新代码集成到旧版本中的主要模式之一。

9. 计划B或集成的回滚计划。 许多人犯了忘记它的错误。 在浇注新材料时“出现问题时”的情况至关重要。 就是说,一旦我们开始构建体系结构,就已经在这个阶段了,我们应该了解在出现错误的情况下如何回滚它。

10. 没有(码头)测试的新代码将在一周内成为历史。 不管您的代码多么漂亮,如果没有文档记录,一周之内就处于“旧版”状态-因为它难以理解。

11. 测试。 如果单元测试太昂贵,那么我们将使用烟雾测试,功能测试和集成测试。 向一家酱油企业出售单元测试以“使工作变得美丽”有多现实? 在我们的现实中,这是一种罕见的现象,而不是一种模式。 如果由于某种原因它不能与“单元”一起使用,则我们转向烟雾测试,功能测试或集成测试,并且不要忘记我们可以将任务委派给例如手动测试人员。

而不是结尾


这个故事中最重要的事情是做好工作,而不遗漏6个有问题的阶段(按从简单到复杂的顺序列出)的遗产:

  • 没有技术文件
  • 没有商业文件
  • 没有人开发这个
  • 我们不知道用户应该收到什么。
  • 每个函数的使用量超过200,它们称为getA()
  • 没有人愿意/可以发展这一点。

Source: https://habr.com/ru/post/zh-CN431562/


All Articles