随着时间的流逝,系统可能会发生很多丑陋的事情。 这就是关于技术债务的争论的全部内容–由于草率和短视决策,如何防止代码变得丑陋,脆弱,难以理解,以及随着时间的推移维护成本更高。 但是,代码中发生的最丑陋的事情与技术债务无关。 它们是有意识且精心设计更改的结果。

善意的更改可以创建难看的代码

当您决定重新架构或重写系统或开始进行大规模重构时 ,可能会发生坏事,但您无法完成工作。 其他更重要
在完成将所有代码过渡到新设计或新平台之前,需要进行工作–也许这永远不会发生,因为您没有预算和授权来完成整个工作。第一名。 或者是开始工作的人离开了,没有其他人足够了解他们的愿景以实现它–或没有人关心它以完成它。 或者,您仅够解决您或客户真正关心的任何问题,而没有继续前进的良好商业案例。

现在,剩下的就是我的同事所说的“ Frankensystem”:不同的设计和不同的平台以有效的方式拼接在一起,但是却很难理解和维护。

为什么会这样? 您如何阻止系统变成这样的怪物?

通过抽象分支

至少在短期内,可以弄乱代码的一种方法是通过“ 抽象化分支”(Branching by Abstraction) ,这种想法在商店中很流行,因为Dark Launch通过持续部署或持续交付而发生了变化。

在“按抽象分支”(也称为“代码分支”)中,每个人都在主干中工作,而不是创建功能分支来隔离代码更改,然后在完成后将更改合并回去 。 如果需要进行较大的代码更改,请先编写临时脚手架(抽象层,条件逻辑, 功能部件之类的配置代码)以隔离您需要进行的更改,然后您可以直接在以较小的增量步骤编写代码主线。 在完成所有工作之前, 脚手架可保护系统的其余部分免受更改的影响。

按抽象分支试图解决管理功能分支 (尤其是寿命长的分支) 滥用的问题-如果您不让开发人员分支,则无需弄清楚如何使所有分支保持同步并管理合并冲突。 但是,通过抽象分支,直到工作完成并删除临时脚手架代码,该代码将更难以维护和理解,并且更加脆弱和容易出错,正如James McKay指出的那样 :


“……可见与否,您仍在将代码部署到生产中,因为事实证明该事实存在错误,未经测试,不完整,甚至可能与实时数据不兼容。 您的if语句和配置设置本身就是受错误影响的代码-而且只能在生产中进行测试。 他们还付出了很多努力来维护,以致于很难用手指来指某些东西。 意外暴露是一个巨大的风险,很容易导致安全漏洞,数据损坏或商业秘密丢失。 您的功能可能不会像您以前想象的那样相互隔离,并且最终可能会在您的生产环境中部署错误。

如果您决定像这样在代码中分支(在某些情况下我们进行代码分支,而在其他情况下进行功能分支–代码分支则适合于进行幕后的管道更改,而不适合于大型功能更改),小心。 检查您的脚手架以确保代码更改完全隔离,并使用新旧配置(关闭和打开)进行测试以检查回归。 最大限度地减少团队一次发布的更改数量,以使更改没有重叠或冲突的机会。 为了避免“抽象分支”成为维护的噩梦,请确保在完成后立即删除临时脚手架。

半-死的僵尸

按抽象分支可能会导致代码难看,至少要花几周或几个月才能推出每个更改。 但是,如果您尝试以增量方式对系统进行主要的重写或重新架构,则代码中的情况可能会变得更糟,例如,使用新代码和新设计“扼杀”现有系统 (由ThougtWorks创造的另一种方法),以及慢慢使旧系统窒息 。

扼杀系统可以让您引入新的设计或切换到新的现代平台,而不必先完成漫长而昂贵的重写。 扼杀工作通常由一个单独的团队并行完成,让其余团队维护旧代码–这当然意味着在进行更改和修复时,两个团队都需要保持同步。

但是,如果您没有完成工作,您将留下一种僵尸,一种令人恐惧的半死半活的东西,上面有难看的接缝,正如Nat Pryce在此Stack Overflow帖子中警告的那样:


“要克服的最大问题是缺乏实际完成扼杀的意愿(通常是非技术利益相关者的政治意愿,表现为预算不足)。 如果您没有完全杀死旧系统,那么您将陷入更糟糕的困境,因为您的系统现在有两种方法,两者之间的界面很笨拙。 后来,另一波开发人员可能会决定扼杀那里的内容,编写另一个扼杀器应用程序,而又由于缺乏意愿,可能会通过三种处理方式使系统处于更加糟糕的状态。

我已经看到关键系统遭受了这两种命运的考验,最终出现了大约四到五个“战略架构方向”和“未来状态架构”。 一个大型的多站点项目最终在其新架构中使用了八种不同的新持久性机制。 另一个以两种不同的数据库模式结束,一种用于旧的工作方式,另一种用于新的方式,这两种模式都从未从系统中删除,并且还有多个类层次结构映射到这些模式中的一个甚至两个。 '

扼杀策略以及其他用于重新架构系统的增量策略,将使您在编写新系统的所有工作完成之前就尽早向客户展示收益。 这既是优点也是问题。 因为一旦客户开始得到他们真正关心的东西(一些漂亮的新屏幕或移动访问渠道,更好的性能或更快的规则更改周转时间……),您可能就无法使业务案例完成剩下的工作。 每个人都理解(或应该),这意味着您会陷入一些不一致的地方–肯定在内部,甚至在外部。 但是无论做什么工作,至少在短期内,保持混乱运行的成本可能比完成重写的成本低得多。

科学怪人和僵尸无处不在

在大型系统上,尤其是大型的,关键任务系统上,怪物的制造比通常情况下要频繁得多,许多人长期以来一直在使用这种系统。 正如Pryce所警告的那样,它甚至可能在一个大型系统的生命周期内发生多次,因此您最终将几个半实现的体系结构移植在一起,从而造成各种令人讨厌的维护和理解问题。

在进行更改或添加功能时,开发人员将不得不决定是采用旧方法还是新方法(或另一种新方法)–有时他们需要同时进行这两种操作,这意味着使用不同的工具跨不同的体系结构工作和不同的语言,并且经常不得不担心保持不同的数据模型同步。 这种复杂性意味着容易出错或遗漏或误解某些东西,并且测试可能比编码更丑陋。

当您开始逐步改变系统的方向和设计时,您需要意识到这些风险,即使您认为自己有决心和时间来正确完成工作。 因为您很有可能最终会创建一个必须与之共存多年的怪物。

参考: Building Real Software博客上来自JCG合作伙伴 Jim Bird的Frankensystems,半缠僵尸和其他怪兽 。

翻译自: https://www.javacodegeeks.com/2013/01/frankensystems-half-strangled-zombies-and-other-monsters.html

科学怪人,半死僵尸和其他怪物相关推荐

  1. 音速索尼克 怪人_科学怪人,半死僵尸和其他怪物

    音速索尼克 怪人 随着时间的流逝,系统可能会发生很多丑陋的事情. 这就是有关技术债务的争论的主题–由于草率和短视的决策,如何防止代码变得丑陋,脆弱,难以理解,以及随着时间的推移维护成本更高. 但是代码 ...

  2. 我的世界服务器盖亚3缴械修改,我的世界盖亚魔典3mod教程怪物系统介绍

    小编为大家带来了<我的世界>盖亚魔典3mod教程怪物系统介绍,模组作者意图是让这个模组充满挑战,给玩家带来独特的体验,所以添加强大的怪物,使它们能够让高端的玩家得到锻炼与增强,这里小编就为 ...

  3. 科学怪人的程序员测试网络安全

    UT达拉斯的电脑科学家们正在试图保持领先一步的网络攻击者通过创建自己的怪物.他们的怪物可以遮盖本身,因为它抢断和重新配置信息在计算机程序中. 部分原因是由于潜在的破坏性,他们的技术,创作者命名为软件系 ...

  4. 僵尸计算机,第二课 事件-僵尸[计算机科学入门(Minecraft)]

    实践 这本实践中,你将重现大群僵尸泛滥的体验.你也会体验指数增长的效果:每次你杀死一个僵尸,将会产生更多的僵尸.那会是怎样的感觉?让我们看看吧! 你将使用当animal被杀死时事件处理程序来触发新的僵 ...

  5. 全球互联网的致命软肋——边界网关协议

    这个27年前的互联网协议让数据任由劫持,搞定它就可以搞定整个互联网 三张餐巾协议 那是在1989年,当两名工程师在共进午餐的时候,互联网的扩展日益严重,一些问题已经变得可怕起来,曾经是计算机科学家眼中 ...

  6. 重温与解析《最后生还者》的互动叙事精髓(上)

    注:本文仅涉及第一部<最后生还者>剧情的讨论,不会对尚未发售的最新作有任何实际剧透内容.请自行决定是否阅读文章. 我想关注业界新闻的人应该也都知道了,就在不久前,由于一些备受争议的原因,导 ...

  7. 我的世界java1.14刷铁机_我的世界1.14版刷铁机怎么做?

    我的世界minecraft1.14版本的刷铁机与1.14之前版本的刷铁机是不一样的.铁傀儡生成的条件在1.14版是村民,有效门,床,工作方块和钟.刷铁机的样式有很多,那么以下就是本人自己试验得出来的一 ...

  8. 我的世界java有三叉戟杀手吗_我的世界-三叉戟竟能这么用 这样得怪物头颅长见识了!...

    <我的世界>海洋版刚刚更新不久,Wiki上关于海洋版的很多特性实际上就是错误的,或者是说测试版中的特性.于是就流传出很多关于"三叉戟"不为人知的特性,经过验证放可知真假 ...

  9. Linux 僵尸进程可以被杀死吗?

    在 Unix 进程模型中,父进程和其所产生的子进程是异步运行的,所以如果子进程在结束后,会留下一些信息需要父进程使用  wait  /  waitpid  来接收.而如果父进程太忙了,没有调用  wa ...

最新文章

  1. python文件读写_python文件操作-读写删除复制总结
  2. UNIX中文件描述符和文件指针
  3. 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 使用 Category 分类注入方法 )
  4. Fabio技术手册(1):概述和快速上手
  5. 老司机的应用级监控——spring?actuator
  6. 大数据之Kafka入门简介
  7. java进程内存一直没释放_五分钟彻底搞懂你一直没明白的Linux内存管理
  8. vs2010中引入boost库
  9. Java面试 - List和Set比较,各自的子类比较
  10. Android技巧:ListView去掉橙黄底色
  11. 代码修改之后MSbuild编译不出最新的dll解决方法
  12. 2022最新版VMware虚拟机及CentOS-7安装教程
  13. 免安装版MySQL的配置——详细教程
  14. 一分钟解决微信小程序截图(截屏问题)
  15. Java实现阿里云域名动态解析,DDNS功能
  16. 小程序{errcode:40029,errmsg:invalid code, hints: [ req_id: 8H_oSa0564ns12 ]}
  17. uefi装完系统后无法引导_uefi模式怎么重装系统|uefi重装系统教程
  18. 微信公众号的二维码怎么生成
  19. 《Web前端工程师修炼之道》学习笔记
  20. 我的世界java版高效率刷怪塔_我的世界超高效率刷怪塔制作教程 砍怪砍到手抽筋...

热门文章

  1. 中国电信物联网发展研究中心与华为战略合作协议
  2. 核高基向左,生产性服务向右,只是完整的左右手而已
  3. 流畅的python 对象引用 可变性和垃圾回收
  4. Centos 7 下joomla简体中文版安装
  5. 个人训练赛第二十场:对撞
  6. mongoose http 源码解析(1)
  7. 一文看懂中国的运营商入库认证(中国联通入库指南)
  8. Group by隐式排序,一个优美的BUG
  9. 机器学习(一) 机器学习概述
  10. NAO机器人——运动控制(1)