设计寿命超过40年的Web应用程序的建议


73

情境

目前,我是一个医疗保健项目的一部分,其主要要求是使用医疗保健提供者使用用户生成的表单来捕获属性未知的数据。第二个要求是数据完整性是关键,并且该应用程序将使用40年以上。我们目前正在将过去40年的客户数据从各种来源(纸张,Excel,Access等)迁移到数据库。将来的要求是:

  • 表单的工作流程管理
  • 表格进度管理
  • 基于安全/角色的管理
  • 报告引擎
  • 手机/平板电脑支持

情况

在短短6个月的时间里,当前的(合同制)架构师/高级程序员采用了“快速”方法,并设计了一个较差的系统。由于他已经设计了一些bean来对数据库执行“删除”操作,所以数据库未规范化,代码已耦合,层没有专用目的,并且数据开始丢失。代码库极度膨胀,并且由于数据库未标准化,因此有些作业只是为了同步数据。他的方法一直是依靠备份作业来还原丢失的数据,并且似乎不相信重构。

将我的发现提交给项目经理之后,建筑师的合同结束后将被撤职。我已经获得了重新架构此应用程序的任务。我的团队由我和一名初级程序员组成。我们没有其他资源。我们已经获得了为期6个月的冻结要求,在此期间我们可以专注于重新构建该系统。

我建议使用像Drupal这样的CMS系统,但是由于客户组织的政策原因,该系统必须从头开始构建。

这是我第一次设计使用寿命超过40岁的系统。我只从事3-5年使用寿命的项目,所以这种情况非常新,但令人兴奋。

问题

  • 哪些设计考虑因素将使系统更“面向未来”?
  • 应该向客户/ PM问什么问题,以使系统更“面向未来”?

59
将来的证明是一回事,但是我相信客户要求的软件寿命比当前的移动/平板电脑计算历史长10到20倍,或者比该语言的当前历史长5到8倍。使用中...对给定计算模型的稳定性过分乐观。

31
设计为40年以上的“未来证明”听起来像是徒劳的活动。
whatsisname 2013年

10
为了满足数据库在未来40年有用的要求,我将其全部记录在纸上。纸张已经证明了自己,而数字存储大部分已经证明了如何快速丢失大量数据。(但是当然保留了所有应该销毁的数据)
Pieter B

34
他们要给两个合同开发人员6个月的时间来构建此系统吗?收集多年的旧数据并在未来数十年内预测新的需求?如果您还没有离开该项目,请开始运行。这比两个人在接近规定的时间范围内能够处理的事情更大。客户有完全不合理的期望,并且不愿意为该项目投入适当的资源。
肖恩·麦克索明

12
2个人需要6个月来设计和实施需要持续40多年的应用程序?不管您有多好,这听起来都像是失败的准备。如果您不能说服您的组织这样做是不合理的,那么我建议您开始尽快寻找其他工作。
dsw88

Answers:


132

数据为王

我认为期望大约在2013年左右的Web应用程序在2053年仍然可以启动并运行是有点不合理的。技术将发生变化。平台将会来去去去。届时HTML可能是一个古朴的记忆。但是您的数据仍然存在。

因此,数据是您的主要重点。只要您的数据仍然存在,人们就可以适应出现的任何新技术。确保您的数据方案经过深思熟虑,并且非常适合扩展。花点时间指定它们。

关于实际应用,您的公司在这里有一个“从头开始构建”指令可能是正确的。我维护着两个有10多年历史的Web应用程序,我很高兴他们没有被2003年流行的CMS系统所锁定。它们使用本地生成的非常简单的框架。我认为对于这样的事情,最好使用专门为项目需求创建的非常基本的框架。

但是现实是,超过40年的时间,该公司将(希望)提供大量的前端和后端服务以适应不断发展的平台。因此,鉴于此,我的目标是面向个人用户的应用程序的使用寿命为5到10年。


13
“我们将在40年内不再使用此代码!” 这就是为什么要开始出现Y2K错误的原因。期望代码被替换只是一种不好的做法。
DougM

71
Y2K“错误”是一个数据问题-存储了2位而不是4位。这就是为什么我建议专注于数据的原因。
2013年

24
好点子。记住这一点,如果有人真的希望从现在起40多年后才能使用他们的数据(可能还有数据库),那么最好设计具有尽可能少的特定于供应商的功能的数据库。谁需要解散/重写依赖于特殊Oracle / MS-SQL / 20年后的所有功能的所有代码,对您将不满意。;)
FrustratedWithFormsDesigner 2013年

4
这是可靠的建议。有许多最初运行于20-30年前的Cobol程序仍在运行。尽管技术日新月异,但是如果您的数据和对象模型是可靠的,并且仍然对数据感兴趣,则您的代码将以某种形式或其他形式继续使用。
Bobble

7
由于有人提出了Y2K,请注意UNIX Y2K(en.wikipedia.org/wiki/Year_2038_problem)。
MrFox

40

我们生产付费客户使用了20多年的软件。该代码库使几代源代码控制工具的寿命更长了。除了平板电脑外,我们的软件还可以满足您的所有要求。

其中一些问题包括ESIGNUETA。我们的律师认为,我们需要使电子记录的可读性至少保持10年。对于那些保留完整的文件,你应该看看PDF / A

对于您的数据库,不必太担心规范化。取而代之的是,您应该关注记录所有内容并拥有审核表来跟踪数据中的更改/删除。升级版本时,计划并行测试新版本足够的时间,以确保已迁移数据。新版本的测试还包括新的操作系统-多年来,我们遇到了一些非常不愉快的惊喜。如果需要回滚,请保留安装介质和许可证密钥。测试备份。如果要序列化要存储在数据库中的对象,请以XML代替开发框架提供的序列化。

对于您的人员配置,长期的代码库需要长期的存储。理想情况下,您希望周围有很长一段时间的人。如果这在制度上是不可能的,那么您需要使用Wiki之类的文件来记录所有内容。我的建议是可以与您的错误跟踪系统配合使用的Wiki。

对于您的代码库,请确保您的代码中包含注释。从一个版本控制系统迁移到另一个版本控制系统几乎总是会丢失您的签入注释。我喜欢在规范和错误编号之后命名单元测试。这样,如果单元测试Test_Bug_1235 失败,那么您知道什么以及在哪里追踪应该进行的测试。它不像命名测试那样“性感”,Check_File_Save_Networked_Drives但不同于,这种测试很难回溯到规范,要求或错误Test_requirement_54321_case_2


多谢您分享经验。我肯定需要完成一些工作,因为当前的架构师没有评论他的任何代码,也没有提供任何文档。这一直是后勤上的噩梦,但我希望能改变这种状况。我绝对会调查PDF / A,因为这是我们客户需要的-特别是对于审计。再次感谢您的建议!
皮特

4
这是一个全面且经过深思熟虑的答案。您可以很好地说明审计的重要性,既可以更改数据和数据质量,也可以出于法律原因跟踪谁在查看哪些数据,请参见HIPAA。如果要在美国使用您的软件,那么您将具有此法律要求的某些安全性约束和要求。
maple_shaft

3
… 使用完整提交历史记录,至少可以将SVN转换为git
Feeela

不仅是SVN到Git,而且是大多数非石器时代的系统,尽管像CVS这样的旧系统通常需要使用后收骨者进行手动调整。大多数导出器也会发出git-fast-export流,该流非常简单,它也可以由非Git VCS导入。
grawity 2014年

2
我建议您不要在错误跟踪和规范编号之后命名测试,因为:a)错误编号倾向于从0开始(因为似乎没有人喜欢> 5位数字并且交换了错误跟踪软件; b)规范倾向于迷路(丑陋,但经常发生);c)性感的名字常常使人很清楚。不过,引用spec / bug ID 总是一个好主意。
bernstein 2014年

29

我认为您应该花六个月的时间来解决原来的架构师所造成的问题,并建立合理,健壮的体系结构,并且不要花20个月的时间来解决这个应用程序将如何继续运行。从那里前进。

在医疗环境中,数据库的部分非规范化不一定完全是意外的。医学数据库的某些部分具有使其适合EAV(实体/属性/值)模型的特征。


2
@ user2708395请注意EAV设计,因为它可能不是最有效或最不容易查询。这也可能不是报告的好选择。
maple_shaft

@maple_shaft这也是我读过的。我会非常谨慎,因为我听到了一些恐怖的故事,人们都在滥用它。由于客户端每月只生成一次报表,因此希望使用某些报表数据库使查询更加容易。
皮特

4
@maple_shaft:通常将数据从EAV架构/数据库提取到单独的报告架构/数据库。
FrustratedWithFormsDesigner 2013年

@FrustratedWithFormsDesigner这是一个很好的观点。EAV提供的模式灵活性是无与伦比的,但对于所有持久性而言,它当然不是灵丹妙药。
maple_shaft

虽然我同意可以使用EAV,但您会发现它们之间的关系会让您感到惊讶。就是说,在这类行业(医疗保健,客户关系等)中经常出现的额外属性确实必须摆放某处...只需确保使用属性键表支持它,以获取有关该属性的规范列表属性。
Clockwork-Muse

13

从前端角度回答:

不要听每个人都说不可能做,因为我在1996年共同编写的一个实验性旧金山州立大学Web服务终于在几年前进入Internet天堂,并且在那段时间根本不需要修复任何浏览器兼容性; 这几乎是您40年目标的一半。而这种基于JavaScript的前端我在1998年的斯坦福研究院项目与华丽的东西,几年后更换,但没有理由原有UI不能今天仍然可以运行有轻微的兼容性修补。

诀窍是确保您的应用仅使用广泛支持的W3C / ECMA标准,并在您的控制下设计简洁。虽然许多使用90年代新潮技术编写的Web应用程序目前无法很好地工作或根本无法正常工作,但按照主要标准编写的90年代Web应用程序仍然行之有效。他们可能看起来不错,但可以工作。

这里的目标不是编写一个可以在其服务器上运行并保持40年而又没有人再次触摸的Web应用程序。它的目的是建立一个可以在数十年后仍可使用的基础,它可以成长为支持新功能而不必从头开始构建。

首先,您必须按照官方标准编码,而只能按照官方标准编码。没有JavaScript功能不是批准的ECMAScript标准的一部分;ES5.1是当前版本,通常受支持,因此可以安全地定位。同样,当前版本的HTML5,CSS和Unicode也不错。没有实验性的JavaScript,CSS3或HTML功能(具有供应商前缀或浏览器之间没有100%协议的功能)。而且没有针对浏览器的兼容性黑客。您可以在标准中加入新功能后就开始使用它,并且所有人都支持不带前缀的新功能。

对ES5的支持将意味着放弃IE8或更早的版本,无论如何我还是建议这样做,因为它需要特定于浏览器的黑客,这在几年之内将无用。我建议使用ES5的严格模式,以获得长寿的最佳机会,这实际上将您的基准浏览器兼容性设置为IE10和其他所有人的最新版本。这些浏览器还对HTML5的许多表单验证和占位符功能提供了本机支持,这将在很长的一段时间内有用。

新版本的ECMAScript保持与旧版本的兼容性,因此,如果代码是根据当前标准编写的,则采用即将推出的功能会容易得多。例如,使用即将到来的class语法定义的类将与使用当前constructor.prototype语法定义的类完全互换。因此,在五年内,开发人员可以在不破坏任何内容的情况下,逐个文件地将类重写为ES6格式-当然,假设您也具有良好的单元测试。

其次,避免使用流行的JavaScript应用程序框架,尤其是当它们更改您对应用程序进行编码的方式时。骨干风靡一时,然后是SproutCore和Ember,现在是每个人都喜欢推广的Angular框架。它们可能有用,但也有一些共同点:它们经常破坏应用程序,并且在新版本问世且使用寿命长存有疑问时要求更改代码。我最近将Angular 1.1应用程序更新为1.2,必须重写很多代码。同样,从第2骨干到第3骨干也需要进行许多HTML更改。标准发展缓慢是有原因的,但是这些框架发展很快,而定期中断则是代价。

另外,新的官方标准通常会使旧框架过时,而一旦发生这种情况,这些框架要么变异(随着重大更改),要么被抛在后面。您知道一旦ECMAScript 6被批准并且所有浏览器都支持其标准化的Promise类,世界上所有竞争的Promise库将会发生什么?他们将过时,他们的开发人员将停止更新它们。如果选择正确的框架,您的代码可能会适应得很好,并且如果您猜错了,您将在进行主要的重构。

因此,如果您正在考虑采用第三方库或框架,请问自己将来要删除的难度有多大。如果它是一个像Angular这样的框架,那么如果不从头开始重新构建应用程序就无法删除它,那是一个好兆头,它不能在40年的体系结构中使用。如果它是您使用一些自定义中间件抽象的第三方日历小部件,则替换它将花费几个小时。

第三,给它一个良好的,干净的应用程序结构。即使您不使用应用程序框架,您仍然可以利用开发人员工具,构建脚本和良好的整洁设计。我个人是Closure Toolkit依赖管理的粉丝,因为它很轻巧,并且在构建应用程序时其开销已完全消除。LessCSS和SCSS还是用于组织样式表和构建要发布的基于标准的CSS样式表的出色工具。

您还可以将自己的代码组织成具有MVC结构的一次性类。这样可以更轻松地回到未来几年,并在编写内容时知道您的想法,并仅替换那些需要它的部分。

您还应该遵循W3C的建议,并将演示信息完全保留在HTML之外。(这包括作弊,例如给元素提供表示性的类名,例如“ big-green-text”和“整个两列”。)如果您的HTML是语义的,而CSS是表示性的,则维护和适应它会容易得多。未来的新平台。为盲人或残疾人士添加对专用浏览器的支持也将更加容易。

第四,使测试自动化,并确保您具有几乎完全的覆盖范围。为每个类编写单元测试,无论是服务器端还是JavaScript。在前端,确保每个类在每个受支持的浏览器中均按照其规范执行。对于每次提交,都可以从构建bot自动化这些测试。这对于延长使用寿命和可靠性都非常重要,因为即使当前的浏览器遮挡了错误,您也可以尽早发现错误。Jasmine和Google Closure的基于JSUnit的测试框架都很好。

您还需要运行完整的UI功能测试,Selenium / WebDriver擅长此测试。基本上,您编写了一个程序,该程序将逐步遍历您的UI并像有人在测试它一样使用它。将它们连接到构建机器人。

最后,正如其他人提到的那样,您的数据为准。请仔细考虑您的数据存储模型,并确保其持久耐用。确保您的数据架构是可靠的,并确保在每次提交时都对其进行了彻底的测试。并确保您的服务器体系结构可扩展。这比您在前端执行的任何操作都更为重要。


1
关于“ JS框架”的好建议也适用于后端框架。参见鲍勃·马丁叔叔的建议
Brian Low

坦白说,鉴于上下文,我会谨慎对待JS。我可以想象HTML已经存在40年了。我不会依赖于正在使用的转换器,而不必以所需的方式来支持JS(并考虑到您的JS可能做错了事,因为首选的输出设备可能无法想象地不同)。
Eamon Nerbonne 2014年

10

撇开客户不合理期望的问题并专注于设计问题,我走了不到40年,但您似乎拥有的,具有长期可扩展性的问题正是REST所针对的。我的意思是说,REST实际上是一种体系结构样式,而不是如今与该术语联系在一起的流行词驱动的开发。

在某种程度上,人们误解了REST,因为我未能在论文中包含有关媒体类型设计的足够细节。那是因为我没时间了,不是因为我认为它比REST的其他方面都重要。同样,我怀疑很多人会误解,因为他们只阅读有关该主题的Wikipedia条目,而该条目并非基于权威资料。

但是,我认为大多数人都犯了一个错误:设计简单的东西应该很简单。实际上,设计某些东西所需的工作与结果的简单程度成反比。随着建筑风格的发展,REST非常简单。

REST是数十年规模的软件设计:每个细节都旨在促进软件的寿命和独立发展。

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-724

您提到要使用RESTful接口。该注释本身建议您应该对此进行一些认真的研究,并尝试了解REST的真正含义。您可能只将其与大多数人认为REST的HTTP方法到CRUD操作的映射相关联,但与此无关。

将REST视为Web本身体系结构的形式化。无论哪种方式,十年前或更早以前编写的网络上有很多部分仍然可用,并且可以与今天制作的客户一起使用,因此我们在该部门中找到了正确的方法。我向您保证,这将需要大量工作,因为正确执行REST很难,但是长期的好处是值得的。


这非常有帮助!谢谢。我对REST进行了更多研究,我看到了它的巨大好处以及如何将其扩展到HTTP方法之外。这是非常强大的功能,我很高兴与之合作。也感谢您的链接!我只希望自己有更多的时间!
皮特

9

在阅读完问题和其他(经过深思熟虑)的答案之后,我以为我也将留下两分钱。注意:我根本不需要维护任何真正的旧应用程序/软件。我用作参考的是我自己的正在进行中的业余爱好Web应用程序,该应用程序可以获取一些开放的政府数据,并以不同的格式进行解析和显示。该应用程序最初是一个项目,当时我并不孤单,而政府刚刚宣布它将以某种方式提供此数据。因此很明显,随着时间的流逝,很多事情都会改变。他们做到了。我从中学到的是:

  • 在迷你应用程序中拆分内容。每个人完全有能力自己完成任务。这使得非常快,非常安全且非常容易地切出单个零件。而且,当您必须回头时,不难理解事情发生的原因以及事情的发生方式。如果您或其他人以后需要更改某些内容,则替换单个部分要比整套事情容易。
  • 获得用于不同部分之间通信的可靠的恒定中间件/层。在这种情况下,我使用JSON,但是XML,ini或类似标准也可以。它很容易重复,几乎可以转换成任何东西。所有这些都是经过验证的标准,可以保留相当长的一段时间。即使基础数据和/或存储模型将更改。每个应用程序都可以将自己的数据存储区用于其特定任务。这使任务的扫描数据量更小,因此更易于处理和维护,并且更易于交换。
  • 不用担心编程语言的决定。这些将随着时间而改变。只需确保使用自己熟悉或最适合任务的语言即可。
  • 确保您的数据存储可以“水平扩展”,并且易于插入其他存储模块。
  • 得到一个共同点(在我的情况下是URI),在该处调用迷你应用程序和/或交换数据。

总结:我最关心的事情是关注点的分离和分配给任务的零件的可交换性。您只知道在40年(甚至5或10年)内,硬件,接口,存储等将发生很大变化。之后,开发人员将不得不对这些更改做出反应并交换应用程序的某些部分,无论是数据容器还是用户界面的一部分。


1
很好的建议!谢谢。我绝对同意分离任务和创建迷你应用程序。当前版本的所有内容都是耦合的,因此很难集成新功能和要求。我希望使用RESTful接口并使用JSON。不用抱怨,但是当我第一次加入时,离岸架构师不会让我使用JSON。所以我只是告诉他我正在传递“字符串”,而忽略了这些字符串采用JSON格式的部分。:)
皮特

7

为了使事情尽可能“面向未来”,请计划更改。也就是说,除了可以轻松更改的能力以外,请尽最大努力不对其他任何内容进行优化。因此,没有规范化,没有严格的验证以及松散的耦合效果。

  • 使用主要的开源技术。对于数据而言,封闭源系统是主要的风险来源,因为人们无法计划将要采用的公司或更改策略,因此无法访问所有数据。同样,没有活跃社区的小型开源项目也更有可能失去支持。

  • 使用无模式的NoSQL数据库。诸如MongoDB之类的文档存储所使用的各种非结构化数据几乎完全是教科书。当您知道如何构造数据时,传统的关系数据库及其规范化就很好了,但这确实是虚构的,尤其是在这里。随着系统的扩展,更改RDBS中的架构的成本越来越大。知道现在选择的任何结构都将最终发生变化。

  • 使用广泛接受的标准对系统进行大量解耦。将所有数据访问和突变分解为Web服务是实现这一目标的第一步。将其与消息队列相结合以提交更改,这样将有助于系统的各个部分随时间更改语言或技术。


不幸的是,使用无模式数据库并不意味着重组和重组数据的成本为零。
2014年

4

好的,所以我要在这里说一些可能不太受欢迎的事情,但请在这里坚持。

因为这是您的第一个项目,数据和/或应用程序应持续20多年,并且您是该项目的领导者,所以您需要退后一步,考虑一下该项目成功的几率。因为它们基本上接近零。

您需要花费大量时间专注于数据库设计和正确处理。为了使该项目成功,您需要尽快将一个数据架构师引入该项目。没有一个在数据库设计方面有丰富经验的人,以及一个非常有经验的人在期待将来如何使用数据,那么5年后数据仍然有用的几率比40年少得多。

期望两个人(其中一个人拥有jr。dev的头衔)从头开始构建一些东西(预计将持续40年),可能不会成功。应该有一个团队,其中许多人在处理像这样的大型项目方面经验丰富,他们从事数据设计,API设计和应用程序设计。这样的事情不是2人项目。

想要将项目与Drupal之类的项目联系起来,说明了为什么该项目需要习惯于从事这类项目工作的人员。您不希望将应用程序与可能在短短几年内过时的任何事物联系在一起。如果这样做的话,要在5到10年内找到一个可以在系统上工作的人会非常困难。

我会将此建议带给管理层,并向他们解释,您需要让更多的高级人员来从事该项目。否则,该项目注定要失败,而您最终可能会成为对此负责的人。


3

该应用程序无需经过40年的生存就不会发生任何演变。但是,由于它将或应该从头开始构建,因此它可能仍在“运行”中。

最关键的是“数据体系结构”,该体系结构可以实现一定程度的稳定性和治理以及可扩展性。

我们设计的数据体系结构和分类法几乎可以在人类灭亡后幸存下来,但仍然可以扩展。您会找到一个真正的数据分类/数据架构师来为您执行此操作。


我认为这个项目从一开始就失败了,因为它没有一个合适的数据架构师就开始了。这绝对是非常合理的建议。
皮特2014年

是时候打电话给我并聘请我了:)正如我们所说的,为一些公司做数据治理和分类法:)
Alex S

3

这里的关键是将精力集中在数据库上(如上文所述)。这需要连贯并完整地描述操作。它需要随着操作的变化而增长。如果不容易改变,那么它将过时,那就是死亡之吻。其余的则相对不那么重要。

我不同意上述观点,他们认为规范化并不重要,尽管在某些情况下,当前的系统无法胜任工作。在这些情况下,非规范化但要确保数据库作为原子事务的一部分来处理额外的写入/更改。这样,您可以有效地忽略该问题,直到可以解决它。

我退休前工作的公司正在运行的系统是从头开始编写的,并且已经连续25年增长,并且几乎涵盖了中型零售商的所有方面。我认为该系统很重要的方面是:

  • 整合至关重要。
  • 数据库必须是正确的,并且IT人员和其他人员都可以理解,因此需要对命名进行几乎偏执的强调。我们有定义的助记符表,然后将它们组合起来以构成表和字段名称,所有“代码”都同样被命名为常量并存储在EAV表结构中。
  • 我们将业务逻辑封装到数据库触发器中。起初这很麻烦,并且需要进行其他工作才能将错误消息传输到客户端,并允许在不锁定整个表的情况下灵活地更改触发器,但这很快就节省了大量时间,并迫使数据库更加正确。比其他方式。
  • 假设即使在“删除”状态下,您在系统的整个生命周期中也至少要保留参考表(理想情况下是最快和最不重要的事务,但所有表除外),以便您的参考是正确的。
  • 由于上述原因,请确保长期确定所有唯一标识符和交易号的大小。(我最初是在开玩笑地建议他们需要持续到我退休为止)。

2

我建议使用事件源以及命令和查询责任隔离。这主要是因为您唯一可以确定的是已经出现的事件。可能会出现新类型的事件。因此,即使您对模型进行了沉思,也可以确保它会过时。迁移每个发行版中的所有数据可能不可行。因此,最好的方法是建立一个适合您当前需求的模型,并在每次需要它时从已记录的事件中计算出该模型,然后传递根据该模型的当前状态计算出的事件。

也要考虑测试。如果该应用程序从现在开始已经使用了十年,那么测试人员必须确保该应用程序仍在按其预期的方式运行。因此,使集成测试尽可能容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.