跳转到主要内容

保存的帖子

遗留代码中隐藏亚博vip9通道的业务规则

Dave Nicolette |龙头
戴夫尼科尔特 高级顾问
阅读: 遗留代码中隐藏亚博vip9通道的业务规则

遗留鳕鱼中的隐亚博vip9通道藏业务规则

大型组织通常不愿意替换已经为关键任务业务操作服务多年的非常老的遗留应用程序。亚博vip9通道事实上,他们根本不愿意修改应用程序。这是为什么呢?

在回答这个问题之前,让我们回答这个:

谁在乎呢?

回顾“敏捷”运动的历程,在我看来,当“敏捷”的理念到达创新曲线的早期采集者阶段时,大型公司开始对“敏捷”产生了浓厚的兴趣,而且看起来它似乎不会失败。从那时起,许多大型组织开始实施“敏捷”计划,并且有相当一部分做了多次尝试。“伸缩框架”和“认证”的激增反映了资金雄厚的公司对敏捷性的需求。

成功的故事是关于企业技术环境的外层。“完整堆栈”意味着(仅限)移动和Web前端与Web服务器和应用程序服务器和本地数据库交谈,然后将“真实工作”交给不包含在“敏捷中的后端系统”“ 生态系统。关键任务业务规则被烘焙到后端系统中。亚博vip9通道“完整堆栈敏捷”应用程序主要在客户端设备和通往后端系统的API之间来回传递消息。这些较大的企业中真正的“完整堆栈”根本不涉及。

称之为成功的“敏捷”转变就好比说地球只由地壳组成。地壳无疑是我们人类最感兴趣的部分,因为它是我们可以与之互动的部分。但地底下还有很多,没有它们地壳就不适合居住。

在早期,“敏捷化”外壳足以让客户感觉到公司在前进,并能够有效地对市场做出反应。然而,在某种程度上,该方法讨论了一个更大的问题,即在新应用程序调用api之后,如何处理旧平台上的业务关键型核心系统。亚博vip9通道变化那些系统不适合规范“为期两周冲刺”模型。这有各种原因,从技术到程序到结构到监管。

事情已经进展到这一点成为加强的下一个“弱势环节”。那是怎么做的?有几种选择:

  • 选项1:将后端隔离在API层之后,不去管它,希望一切顺利。
    挑战:随着平台的老化,供应商的支持和合格的技术人员的退休,风险也在增加。这两个可能性影响失败的可能性会随着时间的推移而增加。
  • 选项2:将后端达到最新,并将其折叠到较大的“敏捷”环境中,并停止操作数据中心,就像它仍然是1985年。IBM从未停止过发展大型机平台和相关技术。这样做没有技术障碍。尽管已经难以使这些系统现代化,我们等待更加困难和昂贵的那么困难。
    挑战:价格 - 不是成本就像在成本效益, 但价格。激活zSeries系统上的必要功能和容量是昂贵的。在某些情况下,对现代化系统的努力也可能需要两年或更长时间的公司资源。亚傅体育app这20年前,我们应该开始做,但是当它不那么困难时。我们继承了那个时代短期思维的结果。
  • 选项3:确定遗留应用程序中的关键业务功亚博vip9通道能,并将其划分为微服务或无服务器功能。
    挑战:从遗留语言中提取和重新打包所选例程的努力至少与从头开始重写这些应用程序的努力一样大。此外,由于传递参数和返回值的约定差异,通过外函数接口(FFI)调用以大型机语言编写的子程序为第一次调用,使得包装“救助”传统例程的差异,因此云 -friendly scripts (yes, I’ve tried it). Maybe that’s okay for a FaaS or “serverless” setup, but it feels pretty clunky. There’s also the fact that once we have analyzed the legacy source code sufficiently to identify key business rules hard-coded therein, we also understand those rules well enough to rewrite the application, and that is probably an easier task.
  • 选项4:重写关键应用程序或用现成的产品或基于网络的服务替换它们。
    挑战:确保在翻译中烘焙的市场区分逻辑不会丢失。

这篇文章阐述了关于选项4的主要关注点。

犹豫的原因

客户不愿深入研究长期遗留应用程序的两个主要原因向我表示。首先,他们没有多少(或任何)技术人员可以自信地使用代码。他们担心任何改变都会导致他们无法轻易纠正的回归。

其次,他们担心以神秘的旧语言编写的神秘源代码包含了神秘的硬编码业务规则,提供了一些公司的竞争优势,并且不会在任何地方记录或完全被任何人理解。亚博vip9通道更换或尝试更新旧代码可能会消除该特殊逻辑。我怀疑第二个原因是第一个推论。

有些公司比其他公司更陷入困境。我记得一家重新聘请退休员工的公司,以维持他们最关键的申请。在78岁时,他是最后一个人能够在该系统上工作的人。他们每年支付250,000美元,每周工作2天。他已经完成了ulcan梦想多福多寿,但公司未来的前景如何?

在侧面注意:为什么公司将首先建立这样的解决方案?请记住,在大型企业首次利用早期计算机系统的几年中,没有COTS包或基于互联网的服务。一切都必须从头开始写,所有这一切都是专有的,因此程序员不能从其他人所学到的事情中受益。

这太可理解了。但是,为什么人们会出于设计解决方案的方式,所以奥术和复杂的是,没有其他人可以与之合作?为了探索对苯高诺的理解,学者们创造了一种来自正式逻辑,心理学和称为药理学的跨学科的研究绘图领域,因为当时这一定似乎是一个好主意。这是对这件作品的范围,尽管我们期待阅读(或吸烟)研究结果。

不可读的代码?

让我们来看看组织避免更改旧代码的第一个原因:当前的员工不熟悉编程语言。对于上下文,让我澄清一下,我们主要讨论的是最初在IBM大型机上用汇编语言、COBOL、PL/I或RPG开发的应用程序,以及(当时)使用TAL或COBOL在Tandem不间断系统(现在由HP拥有)上开发的应用程序。我们也主要考虑金融领域的大型、成熟的公司,它们在游戏中很早就采用了计算机技术。这些公司最有可能拥有仍在生产的老式应用程序,其中一些核心应用程序可以追溯到20世纪70年代。

的确,今天的年轻专业人士既没有接受过这些较老的编程语言的培训,也没有对它们感兴趣。他们不想被分流到一个多年的转换项目中,这样会使他们的市场技能失去价值。另一方面,当我们转换代码时一种语言,我们只需要能够理解代码在做什么;我们不需要深入学习语言。

好消息是Cobol占几乎所有的遗留应用程序,我们可能希望迁移或保留。即使在不小心编写时,COBOL也与组装,缩略或RPG(特别是基于表格输入的较旧的RPG版本)相比相对易懂。pl /我不是本质上很难读懂,但人们倾向于写“聪明的”代码;Perl Golf.预测1987年Perl的发明,至少在精神上。

曾经有一段时间,全球生产中的业务应用程序代码有超过97%是用COBO亚博vip9通道L编写的。您可能不需要处理其他比COBOL更难理解的遗留语言。

为什么这么多风格变化?

不仅年轻的同事不熟悉传统语言,而且原始作者并不总是遵循一致的惯例。旧的代码充满了惊喜,有些比其他的更有趣。对于那些必须处理一些更具创造性的一次性设计示例的人来说,对COBOL可读性的乐观评价并不能给他们带来什么安慰。

我已经看到了COBOL的意外“功能”在没有崩溃数百家客户的情况下无法修复编译器的范围;特别是,使用嵌套的使用根据条款来实现运行时的可变长度表,这不是COBOL的定义特征,并且仅在IBM编译器释放中偶然使用事故。一个原始例子Hyrum的法律。我已经看到了基于组装宏的“巧妙”应用程序发生器;一种轨道的一种白垩纪版本脚手架指挥,只是不如主意好。我曾见过COBOL代码直接将目标代码写入WORKING-STORAGE区域,然后将其传递给汇编子程序以动态执行代码;实际上是对静态语言进行monkey-patch。

没有必要把事情搞得那么疯狂,让代码难以遵循。在一些商店中,人们希望实现设计时重用。它们依赖于IBM对COBOL的扩展,该扩展允许嵌套的COPY替换语句。与巨大的单片源文件相反,他们的应用程序包含了大量填充了占位符文本的代码片段。代码可能就命名惯例和缩进而清洁,但是意图代码被混淆了。查看已编译程序的实体打印,并扩展所有copy y,可能是检查源代码的唯一方法……而我们所讨论的可能是70000 - 90000行代码。

今天,每个编程语言社区都在某些公约中解决了。例如,我们通常希望人们在C#中的上部骆驼盒中写入方法名称,即使编译器不在乎,也在Ruby中的蛇盒。有许多小惯例,人们通常在以特定的编程语言工作时尝试遵循。它有助于其他人读取并重用其代码。很容易学习约定,因为我们在“开放”的世界中工作,我们可以在那里找到教程和示例和可轻松共享代码基础。

与今天的“开放”世界相比,20世纪中期的大型机开发世界是“封闭的”。开发人员在每个公司中制定了他们自己的约定和风格,并且在很大程度上不知道在其他公司中使用的约定。我们这些经常从一个组织转移到另一个组织的人有机会看到以多种不同方式设计和编写的代码。总的来说,当时的情况比现在更混乱,尽管我们现在使用更多不同的平台、语言和框架。

我认为这是当时“封闭”世界的结果。没有像万维网、StackOverflow或开源这样的东西。没有人在家里有一台计算机主机。开发人员在工作中学习,除非他们经常换工作,否则他们只能学会一种做事的方法。他们的学习方式可能与隔壁办公大楼的学习方式非常不同。轮子在成千上万的公司中被独立地重新发明,成千上万次。有一个很多制作轮子的方法。

发现隐藏的商业规则亚博vip9通道

幸运的是,我们不必阅读每一行源代码。通过一点练习,我们可以在视觉上扫描模式的源,了解有趣的事情正在发生。出于迁移解决方案的目的,我们对似乎似乎似乎正在做某事看起来令人复杂的东西的代码特别感兴趣,或者使用正确的技术术语“Squirrelley”。

与任何编程语言一样,当您看到一长串不间断的代码、多次缩进的条件语句或试图补偿非有意揭示代码的过多源注释时,您就知道程序可能在做一些不简单的事情。毕竟,COBOL被设计成相对易读的。如果代码的意图不明显,那么肯定有些东西是松鼠。如果代码中有任何有价值的隐藏的业务规则,它们将隐藏在那里,在松鼠之亚博vip9通道中。

静态代码分析

寻找像复杂条件逻辑这样的模式听起来像是静态代码分析的工作。有支持COBOL的产品,比如SonarCOBOL,来自著名的代码分析公司SonarSource强化,现在由Microfocus拥有,是领先的跨平台COBOL提供者。

不寻常的业务规则亚博vip9通道几乎总是与复杂的条件逻辑相关联。设置工具以突出显示包含如下示例中所示模式的源文件。还要查找经常调用的程序或子程序,并直观地检查这些程序的源代码。

期待误报

大多数时候,你不会发现任何值得保存的东西。通常情况下,嵌入在旧源代码中的“特殊”规则相当于人们在很久以前(事物还没有标准化)就想出的破解或变通办法。对于在替换一个遗留体系时可能失去某些重要东西的风险,更多的是发自内心的恐惧,而不是客观原因。

这是一个常见的场景:金融机构处理信用卡账号。他们需要一种方法来测试他们的代码。如果他们使用真实账号测试,可能会发生各种不良的东西。此外,它们不应该访问真实的帐号。您知道,有萨班斯 - 奥克斯利的事情,以及关于个人身份信息的规则。

我想起了一段时间,在后端信用授权系统上工作的同事使用他自己的签证卡来测试代码。当他的账户显示1,000,000美元的余额,而他的信用额度为25,000美元,但签证并不令人愉快。幸运的是,他能够谈论他的方式。

不是每个人都同样擅长谈论他们的方式,所以人们发明了计划识别虚假的帐号。生活在一个“封闭的”世界中,每个人都发明了一个不同的计划。

在所有应用程序代码中,对帐号的任何引用都必须考虑到假号。是的,我知道,这意味着所包含的生产代码被烘焙的测试知识。这是现在的那样。只需滚动它。

这是一种基于帐号的COBOL代码的识别COBOL代码的代码段。

识别部门。驱动程序。CARD1。(代码省略)数据分割。(代码省略)工作存储段。(代码省略)01 WS-RECORD-AREAS。05年WS-INPUT-RECORD。10 IN-ACCOUNT-NUMBER。15填充PIC x(02)。88测试帐户值“99”。 15 FILLER PIC X(14). 10 FILLER PIC X(174). 05 WS-OUTPUT-RECORD. 10 OUT-ACCOUNT-NUMBER PIC X(16). 10 OUT-MESSAGE PIC X(184). (code omitted) PROCEDURE DIVISION. (code omitted) 2200-IDENTIFY-CARD-TYPE. EVALUATE TRUE WHEN TEST-ACCOUNT EVALUATE TRUE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '3' MOVE 'AMERICAN EXPRESS' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '4' MOVE 'VISA' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '5' MOVE 'MASTERCARD' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '6' MOVE 'DISCOVER' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '7' MOVE 'DINERS CLUB' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(5:1) IS EQUAL TO '8' MOVE 'JAPAN CREDIT BUREAU' TO WS-CARD-TYPE WHEN OTHER MOVE 'UNKNOWN' TO WS-CARD-TYPE END-EVALUATE WHEN IN-ACCOUNT-NUMBER(1:1) IS EQUAL TO '4' MOVE 'VISA' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(1:2) IS >= '51' AND IN-ACCOUNT-NUMBER(1:2) IS < '56' MOVE 'MASTERCARD' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(1:2) = '36' WHEN IN-ACCOUNT-NUMBER(1:2) = '38' MOVE 'DINERS CLUB' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(1:4) = '6011' WHEN IN-ACCOUNT-NUMBER(1:2) = '65' MOVE 'DISCOVER' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(1:2) = '34' WHEN IN-ACCOUNT-NUMBER(1:2) = '37' MOVE 'AMERICAN EXPRESS' TO WS-CARD-TYPE WHEN IN-ACCOUNT-NUMBER(1:2) = '35' MOVE 'JAPAN CREDIT BUREAU' TO WS-CARD-TYPE WHEN OTHER MOVE 'UNKNOWN' TO WS-CARD-TYPE END-EVALUATE MOVE IN-ACCOUNT-NUMBER TO OUT-ACCOUNT-NUMBER MOVE WS-MESSAGE TO OUT-MESSAGE . (code omitted)

其基本思想是,代码必须识别测试账号,并以不同于真实账号的方式处理它们。这是遗留应用程序包含的“隐藏业务逻辑”的本质。亚博vip9通道这并不是我们公司区别于竞争对手的特殊处理方式;如果我们替换现有的应用程序,我们可能会失去一个有价值的商业秘密。它与创造竞争优势的有价值的业务规则相亚博vip9通道去很远,它只是管理测试数据困难这一事实的一种变通方法。当我们将解决方案迁移到一个不同的平台或语言时,我们不会携带这种东西。

并非所有传统代码都像上面的例子一样干净。这是一个基于我见过的一些真实示例的等效例程。真实的遗留码可能会对记录程序的完整变更历史记录进行杂乱,因为我们在那些日子里没有非常好的版本控制系统。此示例使用缩进/ else indentation而不是评估,并使用旧的结束每个语句的续惯例,这导致不太相当突破条件块。此示例还具有一些注释的“调试”代码,例如您可能在遗留程序中找到,以及在例程顶部的超出日期评论。即使你不熟悉COBOL,我也想你仍然可以解析它。

2200 -确定-卡类型。************************************************************ * 卡类型开始* * * * 4 = 3 =美国运通信用卡  * ************************************************************ UNKNOWN-CARD设置为TRUE。* display '2200 account ' in-account-number。* chg0826 888-09-05 l fortunata add test acct logic move '0' to ws-test-flag。如果IN-ACCOUNT-NUMBER (1:2) = ' 34 * CHG0313 84-02-12 JK·弗里茨为美国运通或添加37 IN-ACCOUNT-NUMBER(1:2) =“37”* CHG0826 88-09-05 L幸运儿添加测试ACCT逻辑* CHG1144 88-09-05 JK FRITZ添加退出对位如果测试帐号' 1 ' WS-TEST-FLAG执行2295 -流行TST -味精*显示“流行结核菌素后味精”OUT-MESSAGE去2299 -退出设置* chg0555 83-05-19 p mills移动填充消息到自己的para执行2290- population - message go to 2299-exit。* CHG1090 88-06-26 T阮发现如果IN-ACCOUNT-NUMBER(1:2) =‘65’* CHG1128 88-06-28 T阮忘记检查6011 * CHG1184 88-06-30 T阮检查4咬或IN-ACCOUNT-NUMBER(1:4) =‘6011’*显示“发现了”* CHG0826 88-09-05 L幸运儿添加测试ACCT逻辑* CHG1144 88-09-05 JK FRITZ添加退出WS-TEST-FLAG对位如果测试帐号' 1 'PERFORM 2295-POP-TST-MSG GO TO 2299-EXIT ELSE SET DISCOVER-CARD TO TRUE * CHG0555 83-05-19 P MILLS MOVE POPULATE MESSAGE TO OWN PARA PERFORM 2290-POPULATE-MESSAGE GO TO 2299-EXIT. IF IN-ACCOUNT-NUMBER(1:2) >= '51' AND IN-ACCOUNT-NUMBER(1:2) <= '55' * CHG0826 88-09-05 L FORTUNATA ADD TEST ACCT LOGIC * CHG1144 88-09-06 JK FRITZ ADD EXIT PARA IF TEST-ACCOUNT MOVE '1' TO WS-TEST-FLAG PERFORM 2295-POP-TST-MSG GO TO 2299-EXIT ELSE SET MASTERCARD-CARD TO TRUE * CHG0555 83-05-19 P MILLS MOVE POPULATE MESSAGE TO OWN PARA PERFORM 2290-POPULATE-MESSAGE GO TO 2299-EXIT. IF IN-ACCOUNT-NUMBER(1:1) = '4' * CHG0826 88-09-05 L FORTUNATA ADD TEST ACCT LOGIC * CHG1144 88-09-06 JK FRITZ ADD EXIT PARA IF TEST-ACCOUNT MOVE '1' TO WS-TEST-FLAG PERFORM 2295-POP-TST-MSG GO TO 2299-EXIT ELSE SET VISA-CARD TO TRUE * CHG0555 83-05-19 P MILLS MOVE POPULATE MESSAGE TO OWN PARA PERFORM 2290-POPULATE-MESSAGE GO TO 2299-EXIT. * CHG0492 86-07-15 P LING DINER IF IN-ACCOUNT-NUMBER(1:2) = '36' OR IN-ACCOUNT-NUMBER(1:2) = '38' * DISPLAY WS-INPUT-RECORD * CHG0826 88-09-05 L FORTUNATA ADD TEST ACCT LOGIC * CHG1144 88-09-06 JK FRITZ ADD EXIT PARA IF TEST-ACCOUNT MOVE '1' TO WS-TEST-FLAG PERFORM 2295-POP-TST-MSG GO TO 2299-EXIT. ELSE SET DINERS-CLUB-CARD TO TRUE PERFORM 2290-POPULATE-MESSAGE. * CHG1345 90-01-16 BLAKE J REMOVED EXTRA PERFORM * CHG1550 90-01-16 T CONNOR RESTORED PERFORM ELSE SOMETIMES FAILS * CHG1601 90-01-23 BLAKE J SHOULD WORK * CHG1646 90-02-04 T CONNOR WTF BLAKE LEAVE IT * DISPLAY 'Before 2290 call'. PERFORM 2290-POPULATE-MESSAGE. * DISPLAY 'After 2290 call'. 2299-EXIT.

即使您不熟悉COBOL,也可能会发现第一个示例比第二个示例更容易理解。但是,您可以看到代码中有一个模式值得仔细研究:一个复杂的if/else结构。在很多情况下,只有一两个段落或段落块是你真正需要学习的。在遗留代码中识别有价值的逻辑并不令人畏惧。

有许多其他原因可以为一件事或另一件事创造黑客。它并不总是或仅实现测试。重点是,大多数这种东西都不会阻止我们迁移应用程序或完全替换它。

我会重申它是可能的一个旧程序确实包含在其他任何地方没有记录的真正有价值的业务规则。亚博vip9通道但它比大多数人认为的那么不太可能。

下一个>进口在Java中的重要性

发表评论

您的电子邮件地址将不会被公布。必填字段被标记*