| 一个好的系统不仅仅需要满足当前的需求,更重要的在于当数据量,用户数和业务逻辑发生变化时,能够正确地应对这些变化,或者可以很方便地添加对新功能的支持。这就要求系统架构是开放的,可扩展的以及可维护的,同时必须提供用户定制和扩展系统功能的接口。
这个道理大家都知道,但是关键是接口的设计问题。应该提供哪些接口?这些接口都实现什么功能?如何来提供这些接口?本文将和大家一起来思考这些问题。
提供这些系统接口的原因很简单,就是希望系统与外界通过这些接口能够互动起来,外界可以通过它来操作系统功能或者获得系统信息,而系统也能够从外界获得必要的信息,并由此来反映客户的个性化定制。
根据上述目的,一般可以把系统接口分为三类:入接口,被调接口以及双向接口。如果把应用系统看作一个封闭体的话,入接口表示该整体从外界获得信息的通道,比如Hook应用,被调接口表示外界调用该系统的通道,比如典型的API,而双向接口则包括以上两部分的功能,与银行系统的接口就属于该类型。
表一:接口类型
接口类型 典型应用
入接口 Hook
被调接口 API和应用程序被调接口
双向接口 主要是一些和其他系统的特殊接口,包括银行接口,客户数据导入导出接口等
在设计应用系统时,可以根据需求和具体的应用环境来确定提供哪些类型的接口。下面我们就来分别介绍一下这几种类型的接口:
一、API
API(Application Program Interface),应用编程接口是最常用也最基本的系统接口,一般的应用系统都提供API供外界调用,比如常用的Win32 API。你可以把API看作是系统功能子集的封装,用户可以通过编程的方式利用API来达到增加自己功能的目的。当然API的提供也有相当的讲究,比如在一个三层结构的系统中,你可以将客户端组件封装一下就直接提供给用户。但是如果你想提供更灵活的API,你还必须提供与数据库操作相关,以及访问服务器端组件等功能的API。当然这也不是意味着API的功能要提供得越多越好,越详细越好,比如要注意避免将一些执行核心功能的代码暴露给用户。
二、应用程序被调接口
除了API以外,可能还存在着这样一种情况,外部系统希望能够调用你的系统,就好像在Outlook中打开一个.doc的附件时,能够自动跳转到Word中。要实现这样一种功能,你需要提供调用你的应用程序的接口。比如,在一个用户管理系统中,你可能需要提供这样一些功能:外部系统调用你的系统相应的界面来显示用户数据,帐户以及产品信息等。为此,你可能会在接口中提供类似于以下形式的方法:GoToCustomer,GoToProduct,GoToAccount等。
虽然该类型接口不是很常用,但是在有需要的时候将会非常方便。
三、Hook
一般来说,程序编译完成后,程序的运行逻辑就被确定下来,每个用户都只能按照这个指定的顺序进行操作。如果客户希望稍微改动一下这个顺序,你就不得不改变源代码,然后重新编译。比如随着竞争的加剧,用户希望系统增加为老客户免费进行产品升级的功能,而原来系统又没有考虑到这个需求,怎么办?你可能不得不重新修改一下产品维护的界面,在菜单中增加"产品升/降级"一项。如果对于少量的修改还可以接受的话,那么大量的类似修改或者碰到不能修改应用程序的情况,你将束手无策。为此,你可以在系统设计时考虑加入Hook接口。
Hook,本来是指那些能够实现类似于截获系统消息等功能的程序。这里借用来指调用系统外组件的功能实现来覆盖、修改或者增加系统缺省实现的功能,而这些系统外组件的功能可以由客户自己定义,所以也称之为自定义接口。下面我们以在VB中实现Hook接口做详细说明。
图一:系统通过Hook接口与外界的调用示意图
图一从概念上给出了一个大概的描述,图中上部分表示应用系统,而下部分则表示客户自己实现的组件(这里为Client.dll),从图中可以看出它们之间的调用关系,以及Client.dll中的功能实现如何集成到应用系统之中。
详细的步骤如下:
1、 在需要支持定制的地方调用CallAddonDLL方法;
2、 CallAddonDLL尝试创建对象Client.AddOn;
如果Client.dll不存在或者没有被正确注册,则创建失败,应用程序继续接着执行;如果创建成功,则应用程序则转入下面的处理。
3、 CallAddonDLL调用Client.dll中的方法,传入必要的参数;
4、 Client.dll根据传入的参数选择执行不同的操作;
5、 执行完成后返回结果给CallAddonDLL,它可能为以下几种情况:
· 继续--应用程序继续执行接下来的步骤
· 不继续--应用程序将不执行接下来的步骤
· 错误--应用程序捕获这些错误,并显示给用户
通过这个自定义的Client.dll,用户可以定制个性化的处理。比如在显示某个页面之前,系统通过Hook接口调用Client.dll,Client.dll针对这一请求显示一个自定义的窗体,并且返回一个不继续的结果给应用程序,则应用程序将不会继续显示原有的窗体,这样就能够达到用自己窗体替换原有窗体的目的。
四、双向接口
双向接口主要用来进行特殊数据的导入导出工作,比如你可能需要将客户原有系统的数据导入到你的系统中,还有当你的系统涉及到付费信息时,可能需要与银行系统之间进行数据的交换,而且这种交换一般是双向发生的。这个时候你就需要用到这类特殊接口。定义这类接口的关键在于制定出所支持的文件类型和相应的文件格式。
当然,以上这几种类型只不过是形式上的划分,你真正需要注意的是那些可能导致系统发生变化的因素,而针对这些可能的变化在系统设计时就予以考虑。此外,本文只是从系统接口角度来考虑如何实现一个灵活的系统,而这是基于这样一个基础之上的:你的系统架构本身必须是开放和可扩展的,抛开这样一个基础,任何灵活的系统接口都是没有意义的,切不可舍本逐末,比如针对业务流程的差异性和重组的可能,主要还应通过增加应用系统的可配置性来解决。只有一个可扩展的系统架构加上灵活有效的系统接口才能够真正实现一个灵活的应用系统。 |