背景技术
当今的软件系统规模越来越大,一个规模较大的系统通常由功能和运行相对独立的子系统组成。而这些子系统之间的接口的开发一直是困扰软件设计的一个重要问题。
现有的接口开发主要有两种不同的解决方案,下面一一进行描述。
方案一、如图1所示,为方案一的模块示意图。其中Client(客户)模块1、Client模块2、Client模块3、Server(服务)模块1、Server模块2、以及Server模块3分别代表Client子系统和Server子系统的不同模块。
本方案中,在Client和Server子系统之间建立了一个接口(图中为Facade),Client各个模块与Server各模块之间的所有通讯都是通过该接口进行,它包括了Server子系统的各个子模块向Client子系统的各个模块提供的功能。
这种大接口的设计有利于降低子系统间的耦合度,同时单一的进入点使得Client各个模块在获得该接口后,在该接口中即可获得Client所需要的所有接口功能。
发明人在实现本发明的过程中,发现方案一至少存在以下缺点:由于这种接口包括了所有的功能,使得接口本身变得很大,而增加新功能需要改变现有的接口,不易于维护。
方案二、如图2所示,在该方案中每个Client模块与Server相应模块之间都分别对应有一个接口,Client模块首先与Server端的一个中控模块(InterfaceCreator)通讯,向中控模块索取相应的Server模块的接口,中控模块接受请求后,生成相应的接口,并将该信息(如引用信息)返回给Client模块以供其对接口进行使用。Client模块再根据上述信息通过中控模块生成的相应的接口与Server模块进行联络。
发明人在实现本发明的过程中,发现方案二至少存在以下缺点:方案二的缺点是Client模块需要两次、甚至多次与中控模块交互才能获得相应的Server端的接口;同时,当需要增加新的模块时,需要修改Interface Creator以获取新的Interface。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
如图3所示,为本发明中的一种接口获取系统的实施例的组成示意图。该接口获取系统包括第一子系统10和第二子系统12,其中:
所述第一子系统10包括接口申请者100,所述接口申请者100用于根据第一子系统10的相应单元的请求获取相应的接口标识和接口生成参数,并将所述接口标识和接口生成参数发送至接口安排者120,其中,所述接口标识用于标识可生成相应接口的接口生成者122。
所述第二子系统12包括接口安排者120和接口生成者122,所述接口安排者120用于根据接收到的所述接口标识和接口生成参数,通过相应的接口生成者122生成相应的接口实例。
进一步的,如图4所示,所述接口生成者122包括接口类生成单元1220,用于根据所述接口安排者120发来的接口标识生成相应的接口类;获取单元1222,用于根据所述接口安排者120发来的接口类的标识和相应的接口生成参数获取相应的构造函数;接口实例生成单元1224,用于根据所述接口安排者120发来的所述接口类和构造函数生成相应的接口实例。
并且,所述接口实例通过所述接口申请者100和接口安排者120之间的通讯机制从第二子系统12传给第一子系统10。
通过上述描述可知,各个子系统(以Client子系统的模块为例)无须知道怎样去获得其他子系统(以Server子系统的模块为例)中相应的接口,而是由子系统中的接口申请者统一处理。接口申请者与另一系统的接口安排者进行通讯,接口安排者则可以根据相关的信息(如,接口标识等)关联到相应的Server的模块,让接口生成者创建相应的接口实例,并把该实例返回给Client的模块,以供调用。
这样,Client的模块就可以自动获得所需的和Server的模块之间的接口。如果,系统增加新的功能,Client、Server子系统分别增加了新的模块,则这些Client子系统可以通过上述机制自动获得与Server子系统的相应模块之间的接口。该例如图5中所示,其中Client子系统包括Client模块1和Client模块2,Server子系统包括Server模块1和Server模块2,通过上述交互产生接口1和接口2分别供相应的模块调用。
相应的,本发明实施例还提供了一种接口获取装置,该接口获取装置包括类似上述的接口申请者、接口安排者以及接口生成者,其中:
所述接口申请者,用于根据客户端的请求获取相应的接口标识和接口生成参数,并将所述接口标识和接口生成参数发送至接口安排者,其中,所述接口标识用于标识可生成相应接口的接口生成者。
所述接口安排者,用于根据接收到的所述接口标识和接口生成参数,通过相应的接口生成者生成相应的接口实例和接口引用。
所述接口生成者包括:接口类生成单元,用于根据所述接口安排者发来的接口标识生成相应的接口类;获取单元,用于根据所述接口安排者发来的接口类的标识和相应的接口生成参数获取相应的构造函数;接口实例生成单元,用于根据所述接口安排者发来的所述接口类和构造函数生成相应的接口实例和接口引用。
如图6所示,为本发明中一种接口获取方法的实施例的流程示意图。该流程包括:
601、接口申请者根据客户端的请求获取相应的接口标识和接口生成参数,并将所述接口标识和接口生成参数发送至接口安排者,其中,所述接口标识用于标识可生成相应接口的接口生成者。该接口标识可通过配置文件获取。
602、所述接口安排者根据接收到的所述接口标识和接口生成参数,通过相应的接口生成者生成相应的接口实例。
本步具体可包括:
A、所述接口安排者根据所述接口标识通知相应的接口类生成者生成相应的接口类,如,接口安排者利用Java(Java是Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称)的Reflect(反射)机制,通过所述接口标识获取相应的接口类。
B、所述接口安排者根据所述接口类的标识和相应的接口生成参数获取相应的构造函数。
C、所述接口安排者根据所述接口类和构造函数通知相应的接口实例生成者生成相应的接口实例。
603、所述接口实例通过所述接口申请者和接口安排者之间的通讯机制传给客户端。
下面,详细介绍根据上述方法实现的接口生成程序的相关细节。如图7所示,为实现上述接口获取方法的程序的类图。其中,ClientServiceRequester1(服务请求客户端1)、ClientServiceRequester2(服务请求客户端2)是Client端相应的类,对应图5中的Client模块1和Client模块2。ClientServiceRequester1和ClientServiceRequester2中还定义了子函数:method1、methode2和getTaskTakerName。method1、methode2对应功能接口的具体任务,getTaskTakerName用于获取对应的Server段的TaskTaker的名字,如图7所示,method1、method 2就是client模块或者说“类”所定义的功能(在面向过程的语言,如C中也称作function)。
ServerRequester为接口申请者的一种具体实现的类,包括子函数getTaskTaker和getTaskTakerName;TaskArranger为接口安排者的具体实现类,包括子函数getWorkTaker;TaskTaker为Client子系统和Server子系统之间的接口的实现类,但是TaskTaker仅仅定义了接口的公共特性,甚至是一个空的接口,而仅仅为了能够利用Object-Oriented(OO,对象导向)的多态性。
ServiceRequester不需要知道具体的接口。ServiceRequester与Server子系统中的TaskArranger交流,获取相应Server子系统中的模块的TaskTaker的子类(如,命名为xxTaskTaker)的实现者(即接口生成者)来完成任务。
接口生成者生成类AbstractTaskTaker(AbstractTaskTaker1包括子函数method11和method12,AbstractTaskTaker2包括子函数method31和method41)和ConcreteTaskTasker,其中,AbstractTaskTaker是Client、Server相应模块之间的接口类,由ConcreteTaskTasker实现,供ServiceRequester调用,它定义了Server相应模块向Client相应模块提供的接口的功能。ConcreteTaskTasker是Server端相应模块与Client模块间的接口AbstractTaskTaker(对应图5中的接口1、2)的实现,它接受Client发来的请求、并为其提供所需服务。
结合上述程序中关于类的定义,下面详细解释接口获得的流程,如图8所示,包括:
801、Client端的ServiceRequester根据来自Client端的其他相应模块(如ClientServiceRequester1)的请求(如,需要与Server进行通讯的请求),通过一定的方式获取ConcreteServiceRequester所对应的的Server端的TaskTaker的子类名字,如xxTaskTaker(即对应图6中的接口标识),以及相应的接口生成参数。
其中TaskTaker子类的名字可以是把Client的ServiceReqester的前缀放到TaskTaker的前面获得,也可通过配置文件获取相应的TaskTaker的子类的名称。
802、ServiceRequester将获得的TaskTaker的子类名字和接口生成参数(如,参数种类、参数值等)通过特定的通讯方式传到Server端的TaskArranger。
803、TaskArranger获得具体的TaskTask的子类名字后,可利用Java的Reflect机制或其它方式获取处理Client请求的相应的类(如ConcreteTaskTaker1、ConcreteTaskTaker1)。该类可由接口类生成者(如,图中的AutoCreation::ClassCreator函数)生成。
804、TaskArranger通过传来的参数和获取的ConcreteTaskTaker的类名,去获取相应的构造函数(constructor)。该构造函数可ConcreteWorkTaker生成。
805、TaskArranger通过从ServerRequester获得的constructor的值(即接口参数中的一部分)和上述的constructor获取相应的ConcreteTaskTaker的实例。该实例可由接口实例生成者(如,图中的AutoCreation::InstanceCreator)生成
806、通过上述过程获得的TaskTaker的实例(ConcreteTaskTaker)、reference(引用)或remote reference(远程引用)通过TaskArranger及ServiceRequester之间的通讯机制传给Client端的ServiceRequester,然后由各个模块中的具体的ServiceRequester来使用。
通过以上描述可以看出,在本发明的实施例所提供的方法、装置和系统中,各个Client模块无须知道怎样去获取Server子系统中相应的模块的接口,而Server子系统仅根据接口标识和相应的接口生成参数即可自动生成各个具体的模块接口。
这可大大增加了软件的可扩展性,当软件系统/平台需要增加模块时,子系统之间的接口处理机制不用更改,即可处理新增加的功能接口,这也是平台可扩展性的关键。
同时,缩短了软件开发周期,因为无须更改原来的代码,接口处理有自适应的机制,使得软件功能扩展的能力大大增强,而开发周期大大缩短。
并增加了软件的易维护性,软件模块增减无须更改代码,而只需增加或减少相应软件包,增、删、改相应的配置文件即可。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,所述的存储介质可为磁碟、光盘、只读存储记忆体(Read-Only Memory,ROM)或随机存储记忆体(Random Access Memory,RAM)等。
以上所揭露的仅为本发明的实施例而已,当然不能以此来限定本发明之权利范围,因此依本发明权利要求所作的等同变化,仍属本发明所涵盖的范围。