CEO 的日记 - 真正困难的部分






4.51/5 (22投票s)
2005年9月14日
11分钟阅读

51658
原型设计、一些错误的开始和进一步的架构。
如果您刚刚看到这篇文章,您可能想先阅读之前的章节。
引言
在确定了服务器机制和与客户端通信的大致方法后,是时候开始在代码中测试一些东西了。客户端应用程序的设计完全没有确定,但其余部分可以进行原型设计。事实证明,这比设计更具挑战性。作为一项初步的实验性项目,它的优先级相对较低,但最初的几次尝试与预期的最终目标相去甚远。当时,首选的内部开发平台是Delphi,程序员/分析师的早期产品大多使用远程数据集。“好吧,你说你想要多层,Delphi就是这样做的!”他们会说。最终,有必要创建一个简单的示例(从Indy Project的演示程序开始)来演示所需内容。有了这个示例,原型很快就形成了。
第一次错误的开始
原型的第一阶段是创建一个硬编码屏幕,该屏幕将执行以下步骤:
- 接受输入值。
- 将其放入客户端容器。
- 用该信息更新服务器的容器。
- 运行使用更新数据的业务规则(此时是硬编码的)。
- 更改服务器容器中的另一个字段。
- 将其返回给客户端。
- 更新客户端显示。
如图所示:
听起来确实很简单,一旦概念清晰,就变得相当直接。然而,巨大的障碍依然存在。不同的程序员被分配了接下来的两个任务:
- 想出一种方法来识别和运行未编译到应用程序中的业务规则。
- 创建一个可由用户定义的屏幕,可以连接到新的数据对象。
业务规则突然有了自己的生命。相对简单的需求变成了一套高度复杂的XML规范(本质上是一种新的编程语言),由用户屏幕驱动控制流、变量赋值(包括一个完整的表达式求值器)、数据库访问以及运行存储过程的能力。除了非常严格之外,它还将应用程序与单一的数据库平台绑定,并且很难移植到其他操作系统(这是设计目标之一)。经过一些人员调整(以及一些离职),焦点回到了最初的目标。
第二次错误的开始
重新开始业务规则被证明是一个明智之举。最近使用Python进行简单脚本的实验已将其确定为一个不错的选择。它可以在运行时加载,并且有一个可用的库,可以调用脚本并与Delphi来回传递数据。业务规则名称将是Python文件的名称。
确定这个行动方案并制定基本计划花了一天时间。向程序员描述它又花了一天时间。不到一周,整个过程运行得非常顺利。性能相当不错(考虑到提供的灵活性)。进行了对业务规则进行10,000次调用的测试,结果令人满意,足以鼓励继续开发。
在业务规则分散注意力的时候,用户界面部分的开发继续推进。负责这项任务的程序员/分析师与在我们要替换的应用程序中创建了出色的用户字段和用户文件功能的是同一个人。当然,他的方法是为新系统使用相同的机制。需要进行一些重大更改:
- 所有屏幕都需要用户自定义。甚至标准屏幕也可以修改。
- 屏幕上的数据可以是标准应用程序数据,也可以是用户自定义数据。
- 菜单选项需要用户自定义,并运行服务器端业务规则。
- 所有屏幕都需要是非模态的。
几个月内,一个满足所有新要求的应用程序被开发出来。它运行得相当快,并允许用户直接从正在运行的程序中更改屏幕设计(将这些更改放入“层”留待以后完成)。受此进展鼓舞,决定在2004年2月的贸易展上展示原型。由于跨平台兼容性是设计目标之一,因此决定测试这个概念。在两周内,一个服务器和客户端用Kylix(Delphi的Linux孪生兄弟)编译,并且服务器和客户端都在展会上展示。通过简单地更改服务器连接字符串,同一个应用程序可以在带有SQL Server的Windows Server和带有MySQL的Linux上运行。Python业务规则也在两个平台上实现。
尽管这些发展令人兴奋,但仍然有一种挥之不去的感觉,即并非所有设计目标都已实现。似乎客户端不断地被“调整”以添加新功能。仔细检查证明,这个客户端可以做用户想要的任何事情,只要用户想要的是正确的事情。虽然在显示信息方面非常灵活,但控制流高度规范化,并且屏幕的外观几乎是固定不变的。此外,Python业务规则运行良好,但有人担心告诉客户他们需要使用Python来开发他们的规则(尽管计划了一个简单的用户界面)。它也是一个有点复杂的安装过程。
尽管很痛苦,但已经到了一个决策点。是时候重新开始了。这项分析的一部分是我们正在使用的开发工具。我们需要平台独立性。这几乎意味着C++,或者像Java、Perl或Python这样的环境。C++几乎被淘汰,因为开发周期和在运行时连接新业务逻辑的难度。剩下的就是虚拟机和解释器。所有这些平台的性能都是一个问题,再加上编程帮助的可用性。似乎全世界都在转向.NET,但这只是微软,对吧?
.NET进入视野
正是在那时,Mono项目进入了视野。虽然.NET Framework是微软的产品,但他们开放了规范,并且有一个活跃的项目即将发布一个可在Linux上运行的版本。由于当前正在替换的产品只在Windows上运行,因此新产品从那里开始是可以的。只需要有到其他环境的开发路径。 .NET将允许我们编译业务规则并在运行时加载它们。它看起来就是答案。
技能问题
说服现有员工重新开始将是一个挑战。首先,他们都没有.NET经验。此外,他们对自己迄今为止所做的工作感到理所当然的自豪,并且不愿意放弃它。最后,其他优先级(实际上是赚钱的任务)占用了他们所有可用时间。除了为新项目聘请额外的程序员团队之外,只有一个解决方案:外包。
外包
作为一个结果明确的独立项目,这似乎是一个完美的外包项目。内部员工将接受.NET培训,当基础平台交付后,他们将准备好接手应用程序开发。搜索开始了。
由于没有外包经验,有必要缩小范围。互联网上有很多来自世界各地的公司在做广告。由于无法从技术上区分彼此,一个完全非技术性的考虑因素驱动了决策。我们的一位内部程序员是俄罗斯人。俄罗斯有外包公司。我们将使用其中一家。
2004年7月,我们联系了一些公司,提供了项目一小部分的规范。创建一个数据容器,包含数据对象。实现 `IsDirty` 标志以同步两者。使用简单的TCP客户端/服务器机制发送命令包。确保这个简单的任务可以在Mono和Windows下运行。招标要求提供几项答复:
- 你们如何给服务定价?
- 这个迷你项目会花费多少钱?
- 如果这真的很微不足道,请随意将这部分系统作为演示来编写。
发出了十二份招标书,几乎所有都回复了。其中五份有足够的信心制作测试项目。其中两份确实想到了提出问题以澄清真正想要什么。最终,只有三个程序真正完成了所需的工作(其中一个使用了远程处理而不是套接字)。我们确定其中一个项目似乎最接近所需的风格,并且他们沟通良好。由于有很多事情要做,这个开发团队从2004年8月底开始被聘请,以继续工作。正如预期的那样,他们的费率非常合理。
用户界面抽象
有了可用资源,用户界面工作再次开始。这一次,目标是创建一个界面,允许任何平台上的客户端与新服务器协同工作。例如,新系统将有一个基于浏览器的产品,它将镜像内部网桌面客户端版本的所有功能。维护两套独立的用户界面逻辑的前景并不吸引人,即使业务逻辑相同。这个要求导致了一个决定,即将用户界面的规范与其实现分离。简单来说,我们需要能够布局屏幕设计并将其“连接”到数据和处理,而无需实际将其编码到任何特定平台。
正如前面指出的,跨平台开发已经取得了相当大的进展。用户界面是这场盛宴的后来者。虽然有些用户界面在多个平台上运行,但它们很少看起来像原生应用程序。“随处运行”目标的一种方法是在浏览器中实现用户界面。虽然这确实提供了在任何配备浏览器的系统上运行界面的能力,但浏览器不兼容性非常多。当试图“突破极限”时,尤其如此。大多数浏览器可以处理简单的HTML屏幕。不幸的是,将应用程序功能限制在这种简单级别会为任何不仅仅是基本应用程序的东西产生一个糟糕的用户界面。最近有许多努力旨在产生“富客户端”(指体验,而不是成本)。其中一些结果非常好,但最好的仍然无法与内部网桌面客户端上的原生应用程序相提并论。
如何创建一个客户端,它能提供原生应用程序的感觉,可在多个平台上使用,提供卓越的性能,并且相当容易构建?答案涉及几个决定:
- 像浏览器一样,以平台中立的形式提供显示规范。
- 将客户端的“处理逻辑”与显示分离。
- 以平台中立的方式与服务器通信。
- 实现一个平台特定的客户端,它将平台中立的部分与特定的显示接口结合起来。
就像把一堆多米诺骨牌立起来,然后推倒最后一个,每个决定几乎不可避免地导致下一个。设计开始形成。浏览器使用HTML来指定屏幕布局。虽然这是一种平台中立的屏幕布局,但它高度受限且冗长。由于我们在其他地方使用了XML(甚至在我们最初的屏幕布局尝试中),所以在这里也可能是有意义的,但我们需要一种标准的方式来描述布局。于是开始寻找这种标准机制。
再次使用XML
不幸的是,有大量“标准”用于指定屏幕布局。最近的一个是XAML,它是微软Longhorn项目的一部分。它接近正确的想法,但它高度依赖于 `Avalon` 命名空间,非常特定于 .NET Framework,并且(至少在当时)鼓励将代码放置在屏幕中,这不符合设计要求。XAML与 `Avalon` 命名空间的纠缠意味着它并没有做所有需要的事情,反之,做了太多不需要的事情。看起来我们又回到了创建自己的布局和解析引擎的道路上。
然而,布局并非难事。一旦XML布局创建完成,它需要由客户端解释以创建屏幕显示。在持续寻找有助于完成该任务的工具的过程中,有了一个发现,它将永远改变项目的进程。