作为专业的软件工程师,您可能会遇到一个称为MONOLITH #1的架构绊脚石。 整体实质上是企业体系结构中的单层应用程序。 忘记传统的Java EE应用故障,他们将Uber-WAR文件分解为表示层,业务逻辑层和数据库层。 这只是我们的眼神,一个部署到应用程序服务器的WAR文件充其量只是一个整体。
根据我的承包经验,我在软件开发生命周期的各个阶段见证了许多类型的整体。 不幸的是,我已经到了SDLC的下一个阶段,在那之后,整体应用程序已经处于维护模式或已被重申多次。 收缩的本质是,已经确定了位腐烂的条件,并且这些条件是不可逆的。
整体具有以下特征:
- 应用程序代码通常难以理解,因为模块之间有着千丝万缕的联系,使分析异常复杂。
- 在每个里程碑版本中,开发周期的时间逐渐增加
- 有大量的代码和模块。 我要说的是超过50万行代码和250多个模块。
- 令人震惊的是,单元测试类与常规代码的比率非常低,有时远低于5%。
- 通常,组织中只有一两个人知道整个整体如何悬挂在一起的任何线索。
- 有一种抗拒变革的文化。 有时,这种文化是政治性的。
- 人们已经多次穿过针眼
初始化
MONOLITHS是如何形成的? 谁是负责的人? 我对起源有怀疑。 以我的经验,它们是在企业从Brownfield #2环境中生成和构建软件时启动的。
巨石实际上是如何开始的? 它从基本要求或看似基本的要求开始,然后从开始之日起转向庇护。 奇怪的是,无论您是拥有普通工程师还是有一批至少有十年经验的臭鼬工人组成的精干团队,例如,每个人都曾担任过技术架构负责人,这都没有关系。 不幸的是,软件是非常主观的。 我们对最好的框架,最好的库有所有意见,并且由于整体概念的制定,我们受到了知识方面的限制。
为什么将初始条件称为棕地? 因为在原型或stareter版本中很少有案例会从头开始构建所有内容。 如果代码是用Java编写的,则整体结构以Java EE之类的依赖关系开头。 如果您的整体是用PHP,Python,Groovy,Scala或Ruby编写的,那将有所不同。
在敏捷时代之前,整体就是通过大前期设计 (BUFD), 项目启动文档 (PID)和新企业体系结构文档 (NEAD)形成的。
这是我拥有的旧投标文件的摘录:
Universal Trade Desk附加执行摘要:
什么是UTD?为什么要构建它?
如何实施? 什么时候交付,将包括什么? 我们现在在哪? 摘要和未来发展/路线图UTD目标
“这个新应用程序将是近乎实时的交易台附加组件,以X-QuantLib暴露库(X-QEL)可以理解的格式提供合并的单一交易数据源。 UTD的内容将在交易生命周期事件中更新,并可通过API获得。 贸易商将逐步从LEGACY-Y迁移到UTD。 UTD可以在整个Web以及桌面配置文件中使用。”
从上面写于2009年的示例描述中,我更改了一些术语,您可以看到需要严格的业务知识#5 。 如果我在2016年回过头来研究此应用程序,那很可能是单篇文章,并且我怀疑是否会找到描述旅程开始的原始文档。 实际上,我已经签订了一些合同,客户不能再将其借给原始BUFD。
一次性软件和丢失的版本
很久以前,当我在中学学习编程计算机游戏时,我们共享了一台简单的学校计算机,该计算机使用软盘进行存储。 我学习了BASIC编程语言 。 我知道的命令之一是
SAVE A:GAMEFILE.BAS
,它将程序代码的当前状态保存到文件中,其中A:
代表软盘设备的位置。 有一天,在数学,英语,物理,地理,化学等课程的学习之间,我进入了今天的编程领域。 我忘了定期保存程序。 我非常激动,在互动的过程中,我不记得发生了什么事,可能是PC崩溃了,或者我跑到下一课或其他课程。 无论如何,我失去了全部工作。 我真的很生气。 最终,我从记忆中重新键入了所有内容,但是事情终于来了,我想出了如何做得更好的方法。 第二次,我用更好的子程序和新概念改进了游戏。
文化
巨石的特征在于创造它的文化。 有人说,一旦编写代码,您就已经陷入技术负担。 实际上,即使使用单元测试也要编写代码,就像在将来可以选择一样。 如果您知道代码只是一个原型,那么您可以负担得起的工作,并提供给利益相关者留下深刻印象的应用程序的快速工作示例。
独石很少被扔掉或重新启动。 在早期的场景中,应从头开始重建大多数应用程序,但是由于诸如成本,上市时间和财务等业务压力,没有人这样做。 随着时间的流逝,整料不断增长并延伸到远方。
经过多年的努力,这组代码每天,每个月和每年都在增长。 为什么? 因为独占无非是对可行的商业模式的转换,换句话说,只要企业能够获利,那么它将可以自我维持。
迄今为止,单块也是软件工程趋势的受害者。 我们可以看一下技术和库。 最大的Java整体可能早于Spring Framework,Guice和CDI创建。 Java没有注释,甚至没有泛型。 即使是时代的最佳实践也会随着时间而改变。 到2016年, J2EE设计模式已经远远超过了其销售截止日期。 我将添加针对Apache Struts 1.0版编写的控制器以进行混合。
充其量来说,这些单块从未针对组件#3的最佳实践进行模块化或设计。
康韦定律
康韦定律断言,组织受约束只能生成反映其通信基础结构的应用程序设计。 无论组织如何努力适应法律之外的问题,结果总是会导致管理层,部门和孤岛之间的意外通信故障; 所有这些都需要解决。
毫不奇怪,整体将展现出创造并维护它们的人的结构。
员工流动
整体也受到员工流动的影响。 如果新的业务团队从一开始就对应用程序有最初的想法,那么几年后,应用程序的方向将会改变。 老员工离开公司,原始顾问和承包商在新员工到来时离开项目。 新员工必须学习新概念,并且很少以显示最大程度知识转移的方式交接。
抛售
我当时至少遇到了两个整体,这是软件公司的产品。 整体是巨大的,并且按照现代标准,其中至少有一个是极其巨大的,因为它们将JavaScript和现代的前端库作为因素来解决单页应用范式#4 。
由于企业依赖于将其软件作为定制的整体销售给客户,因此最有可能在特定日期完成对整体的扩展。 我怀疑扩展和最终应用程序的价值被低估了,就像行业中大多数软件项目最终到达的价格大大超过了预期的预算一样。
问题在于,单块在逻辑上本身具有不适当的复杂性。 应用程序的扩展取决于几个因素:
- 整体内部工作组件的全面视图
- 新业务需求到技术需求的充分转换
- 适应旧组件并开发新组件
- 处理混合型员工的压力
- 代码,框架和数据库中的未知阻抗
以上是作用在老化的整料上的力。 在SDLC的最开始,这些力量仍然存在,但是代码的复杂性和初始要求较小。
上市时间
由于管理层坚持按预算交付,因此整体式企业遭受损失。 当然,这意味着永远不会对代码进行尽职调查,因此会影响整体生产质量。 开发人员没有时间将代码重构为足够的质量,代码审查干dry了。 在结对发展过程中,必须从政权人物手中spoon取食物,从而摧毁了士气。 编写一个简单的更改(例如向HTML表单添加新字段)需要花费越来越长的时间,因为在结构上,这意味着要通过前端JavaScript框架进行拖曳并更改AJAX。 查找和调整服务器端控制器,更改任何数据库持久对象,然后向众多LiquiBase脚本中添加另一个自拍 XML配置。 工程师会像您想象的那样浪费很多人的时间,因为与您在初学者的书中看到的Java EE CRUD示例相去甚远,然后,管理层想知道开发团队正在归档什么。
缺乏单元测试
根据整体的年龄,它们显示出令人震惊的最小程度的单元测试覆盖率。 根据SonarQube分析#6 ,我见过的最糟糕的整体测试覆盖率为0.2%。
缺乏单元测试表明,上市时间显然是过去的关键因素。 在依赖注入在业界陷入困境之前,就编写了一些应用程序巨石。 静态类工厂单例太多,这使得测试非常困难。 虽然,我看到有一个客户通过Power Mockito获得了不同程度的成功。 即使是那些经过测试的整体,他们也始终没有根据预期的输入来验证或验证足够的输出。
缺乏专门知识
总体上,在依赖注入和模块的情况下,该行业在过去十年中显示出缺乏真正的专业知识。 有效地设计模块化应用程序系统需要花费一些时间,并且大多数人都需要经验。
我们已经在建筑系统中寻找捷径。 在尝试构建面向对象的应用程序和系统方面,我们经过25年的努力。 巨石的出现并不令人惊讶,因为有很多证据表明不应该做: 反模式 。
未能保持最新
随着我们向整体应用程序添加更多的特性和功能,尤其是我们从未抛弃的特性和功能,最终导致复杂性增加了更多的复杂性。 这有点像开放的伤口。 明智的做法是将弹性体涂在上面,因为我们认为这是减轻疼痛和痛苦的最快方法。 然而,开放性伤口并不是直接的伤口。 它需要防腐剂,清洁剂,小型或大型手术,然后用适当的绷带包扎,然后恢复。 软件工程师不会清除错误的代码或更改代码的味道。 它保持感染并变得更糟。
同时软件开发不断寻找崭新的方式。 然后,Java语言会在一年内引入注释。 在接下来的几年中,它引入了功能接口Lambda和Streams。 但是,由于庞大的整体结构具有严重的复杂性和不可理解性,因此几乎不可能使用这些最新功能。 首先,为巨石提供资金并保持良好船舶在船上航行的管理层或利益相关者对任何前进的风险都感到震惊。 对于两个人来说,从政治上讲,而且常常是商业模式意味着他们故意无法使最新的技术保持最新。
整体可以美丽吗?
最近,我听了软件工程电台的节目261担纲很自以为是大卫Heinemeier -汉森的Ruby on Rails的和大本营成名。
DHH描述了他对有关面向微服务的体系结构(MSOA)的炒作的观点。 他认为我们是盲目的,倾向于将新系统设计为微服务。 相反,他将Basecamp形容为受益于动态编程语言的“雄伟整体”。 在过去的十年中,对操作系统功能和CPU性能进行了优化。 DHH反对一开始就反对使用分布式计算应用程序,特别是在小型设置中。
我发现他对于整体应用程序的观点令人放心。 但是,我观察到从一开始,Basecamp就一直处于他的完全控制之下,而我从未见过该代码。 每次将代码签入版本控制系统的可能性都最高。 DHH和Jason Fried是不寻常的,因为他们是坚持使用软件的架构师。 架构师通常会退出编码活动,而大多转向其他软件系统并加入其他公司。 此外,如果不检查应用程序代码,基础架构以及37 Signals的人员文化,就无法看到Basecamp的“美”。 因此,尽管我认为整体作品可能宏伟壮观,甚至雄伟壮观,但要确保随着时间的流逝而保持美丽,这是一个非常高的要求。
商业公司的整体垄断存在严重的不利影响。 它们通常不是开源的,因此,即使是结构工程,安全性和合规性类型,也无法接受独立的严格审查。 我怀疑整体的美在于建筑情人的终结,因此它可以像大棒一样用作杠杆来击败开发人员。 “这就是这里的工作方式,这就是我们拥有的,这也是我们将要做的,以便为里程碑X交付交货。” 换句话说,美不支付账单,巨额薪水和客户的价值。 因此,最后,我们最终完成了丑陋的整体,并且一直持续到关键时刻,这可能是商业模式失败和竞争中的破坏性因素。
Java EE Monolith具有以下特征时,它会损坏:
- 它不是从一开始(5年前)就作为模块化应用程序编写的,在模块化应用程序中模块是自包含的,具有高内聚性和减少的耦合
- 原始的建筑师离开了建筑物和舞台。 而且目前的所有者对内部构造不了解
- 它代表了政治内斗状态,管理权和阴谋诡计
- 组织抵制整体变革,世俗的顾问和承包商很难让管理层倾听
- 明显缺乏单元测试,有时覆盖率不足10%,并且集成测试很困难,因为它比当前的SCRUM冲刺落后一到两个
- 很难解决诸如客户详细信息,测试数据库和有限环境之类的硬代码依赖性。 换句话说,测试最简单的代码变成了一场噩梦。
- 十多年来,这个整体一直严重依赖于遗留库:Struts 1.x,WebWork,Tapestry,Spring Framework 1或2和XML配置
- 标准构建链很复杂,需要很长时间
- 即使管理层突然为今天的整个开发团队开了绿灯,采用Java SE / JDK 9仍将是一个巨大的爬山,而应用程序代码在Java SE 6(2007)的基础上并没有发展太多。
所有这些问题都反映了公司的起源,文化和人员组织。 古老的巨石,到了那里。
翻译自: https://www.javacodegeeks.com/2016/08/ye-olde-monolith.html