作者:Anders小明
2009年5月5日
 

一、什么是基础平台

基础平台对应于业务应用,主要处理技术问题,是为业务应用提供技术支撑以及技术方案的模块或者组件。其目的是使得应用组件可只关注于业务逻辑,而不考虑或者少考虑技术问题。

基础平台通常包括如下:基础功能,开发类库,开发模式以及开发部署工具。

二、为何要基础平台

应用系统的设计可以说是将一个业务语言翻译成程序语言的过程,这个过程同时处理两个内容:业务和技术。

1. 学习业务,编写的代码符合用例的流程;

2. 学习技术,编写的代码符合技术平台的规范和要求。

这里不同底层技术的难易度不同,导致学习成本、开发成本和应用成本也不同。同时对于一个有较长生命周期的软件项目或者产品,其依赖的底层技术的升级也会带来相应的维护成不

面对特定领域的软件项目或者产品,其所依赖的底层技术的广度和深度相对稳定,基础平台可以填平或者减少技术层面的鸿沟。

那么,我们就面临另一个问题,即:业界已经存在大量优秀的开源框架,我们为何要基础平台。

首先,大量优秀开源框架可以帮助我们,但是:

1.优秀的开源框架通常偏向通用性,而面向特定领域的相关特性和功能还不支持;即便有面向特定领域的,其支持的特性还存在一定差异性;同时其未必支持相应的基础设施。

因此需要进行二次开发,以完善所需的基础设施;

2.优秀的开源框架在通用性支持广泛,提供多种选择,同时还有一定学习成本;而面向特定领域,需要的模式相对固定。

因此需要进行定制,减少学习成本,提供开发模式,进而提高开发效率;

3.技术升级的平稳性,虽然优秀的开源框架会尽量提供升级平稳性,但是和产品目标未必一致;也需要进一步的测试工作;为了进一步减少成本和风险需要基础平台来处理相应工作;

4.开源框架本身存在一定的缺陷,其修复有一定周期,和产品项目周期不同步。所以也需要做些修复和规避工作;

因此开发维护支持特定领域的基础平台存在客观需要。更进一步,基础平台是在关注点分离原则下的一个必然产物。

三、基础平台的考核

基础平台的考核需要依照其目标以及特性来,包括:

1. 功能复用所带来的成本降低。这个比较好衡量,直接使用复用。

2. 提高业务应用的开发效率(新增或维护)。这个指标的衡量有一定难度,需要有两个近似项目分别应用不同基础平台,并在一个较长时期内(比如2年,以便消除人员差异、具体功能差异性和难易度)。

3. 技术风险的可控性,技术更新的平稳性。这个指标比较好衡量,需要收集开发过程中处理各种突发技术问题以及其解决成本。

4. 招聘成本。这个指标也属于比较好衡量的。

5. 架构推广。架构推广有赖于一个良好的基础平台,避免成为空中楼阁。

总之,基础平台的应用将使开发和维护的成本具备平稳性和收敛性。

四、基础设施的选型

应考虑几点:1. 商业角度的维护性和升级性;2. 组织的学习和管理能力;3. 基础设施自身功能以及所支持的开发效率.以下是详细要求:

客户角度

成熟度要求

基础设施是业界成熟方案;

性能要求

基础设施满足系统运行的性能要求;

稳定性要求

基础设施版本稳定,经过大量测试;

环境性要求

基础设施不会带来额外的软硬件兼容要求;

管理角度

开发成本要求

基础设施的开发维护成本低,最好是业界成熟开源成果;

开发效率要求

维护成本要求

分析设计与开发之间的衔接性好;

测试成本要求

基于该基础设施的应用测试成本低,效率高;

培训招聘成本要求

网络上的参考资料丰富性;基础设施的流行度;

内部员工学习培训成本低; 招聘外部员工成本低;

五、基础平台的构建

选取基础设施之后就根据需要进行二次开发。包括如下内容:

1. 平台的核心

1.1 领域化支持

领域化的核心是建立业务相关的领域模型以及领域服务。

领域化支持需要三个方面:

A. 持久层支持:这个是领域化支持第一个要素,持久层能够持久化并重建领域模型。

从持久化的方式来看可以分为文件形式和数据库形式,以及二进制形式或文本形式。由于数据库的广泛使用,ORM是常见的方式;但有时这不够,我们可能还在此基础上,进一步扩展提供二进制或文本形式的持久化策略。

B. 业务逻辑支持:包括两个方面:a. 领域模型涉及到的业务逻辑依赖;b.领域模型的并发支持;c. 领域服务的构建;

C. 界面层支持:包括延迟加载以及长会话支持;

领域模型虽然包括所有的数据,但考虑到性能,以及特定界面层所需要的数据通常是子集,因而界面层延迟加载异常重要。而领域模型跨界面传递,即长会话操作,也成为一种必然。

1.2 组件化支持

在组件化技术上,业界现有的规范和开源实现,尤其OSGiSCA都提出了各自的组件规范,并且OSGiSCA有融合方案。但是总体上看,由于其关注的组件元素是最为经典的,在实践应用上还需要有一定扩展。

基础平台需要提供一个简易的组件支持框架,可以支持扫描,识别并加载组件下的各种技术类型资源。包括:界面扩展点,国际化消息文件,应用服务,监听服务,领域模型,配置数据(包括初始数据和运行数据),以及数据库表;

主要包括如下功能:

0. 组件的加载和运行(依赖检查);

分为两个层次:部署期,即部署几个组件就加载几个组件;运行期,根据运行期信息,加载和运行组件。部署期组件体系相对于运行期较为简单,实际上部署期可以完全不考虑组件的边界,而直接加载组件内的不同技术工件;而运行期需要严格明确组件的边界。

1. 组件间集成和交互方法:同步异步,进程内或分布式),包括UI,服务,对象和数据库;

2. 组件间集成和交互的上下文数据传递,如权限和事务等待;

3. 组件的安装、卸载、升级和定制;

1.3 产品化支持

    产品化支持包括了两个方面:

    参数化支持:用户可以通过修改预定义的参数设定调整系统行为。

    定制化支持:包括两个层面:1.用户定制化,即用户通过系统提供的工具进行的定制化;2.系统定制化,即通过开发人员进行编码开发提供的定制化。

1.4 平台化支持

       框架提供相应的事务管理,集成支持和并发处理等等涉及各个技术支持,使得业务应用仅需关注业务逻辑。

2. 平台的功能支持

0. 业务事务与日志

这里提的业务事务,是不同于数据库所提供的物理事务。以B/S应用为例,一个业务事务,对应如下:

a. 一个业务事务:一个web请求,一个服务调用,一笔数据更新;

b. 一个业务事务:一个web请求,多个服务调用,多笔数据更新;

c. 一个业务事务:多个web请求,n个服务调用,多笔数据更新;

对于a,业务事务和物理事务的边界是一致的;而对于bc,显然,由于物理事务和业务事务边界的不一致性,导致基于传统的物理事务是无法跟踪一个业务事务所带来的数据变更。

为了可以跟踪业务事务,就需要通过建立业务事务及其业务日志来记录并跟踪数据的变化。取决于业务应用,更多的时候,只需要跟踪相应历史数据即可。

此外,若需要提供分布式事务(不依赖特定的商业产品),也需要业务事务和日志的支持。

1. 系统操作日志

系统操作日志通常是审计相关的。在严格的审计要求下,业务日志可以提供完整的数据跟踪能力。操作日志相对于业务日志,较为简单,只需要跟踪相应的历史数据。

2. 安全体系

现有基础设施大都提供了丰富了安全体系。不过开源框架尚未提供一种基于数据库,可以由最终用户配置的安全体系。

基础平台需要在如下方面加以完善:

a.    开放角色定义;

b.   开放角色可访问资源定义;

c.    开放角色可访问数据定义;

实际上,bca的基础,只有角色的资源和数据可以定义,角色定义才有意义。

此外,对于可访问数据定义,还存在一定争议,认为此是业务范畴,基础平台或框架不做处理。若要在基础平台提供支持,可以有两种策略:在业务层检查和在数据连接层增强。业务层的检查通常通过AOP技术进行,此种方法存在一定的性能消耗问题,且其适应性存在局限;而数据连接层,则是针对最终的sql语句进行解析和增强,由于SQL是标准,其适应性更强些。

3. 批处理服务

批处理或者说batch处理。

支持不同的触发策略:定时以及手动策略;支持批处理的多步骤处理,包括步骤同一数据、不同步骤不同数据,后一步骤处理前一步骤成功的数据;提供不同的控制策略:包括中断以及暂停;支持不同的批处理策略:串行和并发;支持不同的事务控制策略;完善的运行日志支持;支持不同的运行策略:单机和集群;

4. 打印和报表

对于信息系统来说,打印和报表这两块几乎是少不了的。

一方面是打印和报表通常都需要通过第三方支持来加以实现,一定的开发模式有助于降低学习成本并提高开发效率;另一方面是针对不同应用领域,打印和报表本身存在一定管理需求。

5.系统诊断支持

3. 平台的开发模式

0. 国际化支持

通常提到国际化,最能想到的时文本消息的国际化。文本消息的国际化固然很重要,但是国际化不仅仅包括文本消息。

1.文字消息国际化

对于异步操作或者分布式操作,以及操作日志而言,文本消息并非直接呈现,而是存储于数据库或者文件,并在用户查询时呈现。此时若存储的是国际化后的文本消息,则有局限性:文本消息在产生时决定,而非查看时决定,它的假定是系统的所有用户都是同一个Locale;但是对于拥有多locale用户的系统,因此支持文本消息存储信息为非国际化后结果,而在查询时根据用户的区域转换为合适的国际化文本消息;

2.布局国际化

多数的布局方式是从上而下,从左而右。尤其是界面上的表格布局,通常都是label在左,而输入输出控件在右。这样的布局方式在大部分国家和人群是没有问题的。然而还有另外:阿拉伯国家是从右到左。而中立的做法是label在上,而输入输出控件在下,形成上下布局。这样的布局方式是更为通用。

若要支持两者布局方式的自由转换,在界面不能采用传统的表格布局。同时,label和输入输出控件必需是一个逻辑控件。现有的大量的控件设计都不是如此,label是独立的。因此也封装新的表格控件;

3.业务时间

大部分情况下,一个国家通常只有一个时区,而像美国,俄罗斯这样跨多个时区的国家相对较少。若一个业务系统的用户跨越了多个时区。系统就面临业务时间的处理。即用户的时区和系统所在时区不同。

系统处理业务时必需同时记录两个时间,一是用户所在时区时间,一个是系统时间。而业务程序在处理数据时,必需指明当前采用的时间类型。

此外,数据库层面还需要考虑,并非所有数据库支持记录时区。

4.计量单位,多币种;

国际化面临的另一个问题就是度量衡问题,常见的有英制,美制。用户自行转换制式会带来使用上不便。由基础平台提供封装并自动转换能力。

另一个更为重要的问题时多币种问题。通常发生的交易系统上,交易货币和本位币的不同。系统必须同时记录两个币种,以帮助统计汇兑损失。

1. 异常体系

异常体系的设计

A.异常体系原则

异常属于程序接口的一部分,是除返回值以外的一类输出对象。Java语言中异常分为checkedUnchecked两种,而.NET只有一种Unchecked异常。

B.异常的应用:

异常用于提示(人工处理)或者用于驱动流程。实践中,由于两点原因使得异常通常用于提示(人工处理)而非驱动流程。

B.1.由于异常属于正常流程体系外的输出,属于不受欢迎的输出。通常系统上出现异常后,程序也无法做相应的处理。

B.2.异常在捕获体系上自身的缺陷。OO设计讲究是是抽象和封装,而异常捕获体系是顺序捕获,捕获程序必须了解异常的继承体系,否则一定高层异常早于底层异常则将导致底层异常无法被捕获并处理。

C.异常的分类

异常分为校验错误,业务告警,业务异常和框架异常

C.1.校验错误通常是一种轻量的业务异常,校验错误所依赖信息单一或较少。

C.2.业务异常通常为用户业务数据错误导致的异常信息,通常依赖较多的数据和逻辑。因此针对此类异常只要以友好的方式展示在UI上,用户通过修正输入等方式解决。

C.3.框架异常则是基础平台自身错误,用户无法通过界面操作加以解决,需要开发人员介入修正。

2. 多任务处理

多任务处理包括了异步操作和并发处理两部分内容。多任务处理在技术上属于一个较难的部分,开发以及测试的成本都比较高。

第一个要处理的就是异常的捕获以及重抛出。

其次是并发处理。包括两个部分:并发策略(锁)控制以及并发操作支持。

并发策略(锁)不仅仅是基础平台提供相应框架支持,还是涉及到应用系统的设计包括模型及其服务。这点上目前没有通用的并发框架,只能是根据特定应用领域,制定相应的支持。

并发操作支持,系统提供元数据,自动分解输入参数集合,进行并发处理(可参考Terrecota)。

3. 应用交互模式

基础平台提供基类,同时支持一些约定,封装常用的开发模式,如CRUD,以及异步控制等等面向特定交互应用的开发模式。

4. 平台的类库

0. 工具类

包括类操作,对象操作,断言操作,容器操作等。

1. UI控件

虽然基础设施以及开源界提供丰富的UI控件。但是还是存在一些不足。

第一是UI控件适配性不足,应用系统已经提供各个模型以及服务,但依然需要写代码,而非配置方式;需要基础平台对已有控件扩展,提供适配能力,使得应用组件通过配置将数据暴露给UI控件,从而使得应用组件关注于业务逻辑。

第二是UI控件的国际化支持,详见3.0国际化支持。

第三是UI控件在不同模式下的展示,比如在编辑模式和只读模式下的展示。

2. 文件操作支持

3. 网络通讯支持

包括底层网络通讯(底层网络协议)支持,以及上层网络通讯(应用网络协议,如Web SeviceRMI等)。

4. 参数化支持

5. 平台的工具

1. 打包工具

2. 部署工具

3. 设计工具

4. 生成工具

无论何种工具都是帮助提高工作效率。即它不解决业务和技术的核心问题(核心问题的解决依赖于整体设计方案),而是提供一个加速器,处理所谓的脏活累活。