发明内容
本发明为克服上述问题或者至少部分地解决上述问题,提供一种软件模块间的通信方法及系统。
根据本发明的一个方面,提供一种软件模块间的通信方法,包括:
步骤1,获取第一模块的事件发送请求中所包含的标识hash值;
步骤2,利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;
步骤3,利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
进一步,所述步骤1还包括:利用定义为全局单例模式类的事件发送函数,确认第一模块的事件发送请求所包含的事件是否存在于系统订阅事件集合中。
进一步,所述步骤1前还包括:在软件中各模块接口函数的参数中添加与所述软件中各模块订阅的各事件相对应的标识hash值。
进一步,所述各模块接口函数通过标识前缀开头且所述函数的参数包含至少一个事件。
进一步,所述全局单例模式类的事件发送函数以静态格式存储在内存中。
进一步,所述步骤2中调用所述第一模块外其他模块的接口函数中包含所述hash值的事件并发送的步骤进一步包括:在Java中利用invoke方法,将所述第一模块外其他模块的接口函数中包含所述hash值的事件,发送给各包含所述hash值的事件所对应的模块。
进一步,所述步骤1前还包括:
步骤0,基于系统中各订阅事件的唯一标识,将当前软件中各模块中的订阅事件关联保存在订阅事件集合中。
进一步,所述步骤0还包括:将所述订阅事件集合静态存储在内存中。
进一步,所述步骤0还包括:将所述订阅事件集合为map集合。
在本发明另一个具体实施例中,一种软件模块间的通信系统,包括请求获取模块、函数获取模块和事件发送模块:
所述请求获取模块,用于获取第一模块的事件发送请求中所包含的标识hash值;
所述函数获取模块,用于利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;
所述事件发送模块,用于利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
本申请提出一种软件模块间的通信方法,本发明所述方案具有如下有益效果:1、有效的实现了软件操作系统中不能进行直接通信的各模块的直接交互;2、降低了操作系统中各软件模块直接通信所造成的耦合。
具体实施方式
下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。以下实施例用于说明本发明,但不用来限制本发明的范围。
本具体实施例所指软件模块,是指在程序设计中,能够单独命名、独立编译且独立地完成一定功能的程序语句的集合,包括程序代码和数据结构。
在软件设计过程中,通过会对软件进行模块化设计和划分。所谓软件的模块化设计和划分,是指在软件设计过程中,为了能够对系统开发流程进行管理,保证系统的稳定性以及后期的可维护性,从而对软件开发按照一定的准则进行模块的划分。根据模块来进行系统开发,可提高系统的开发进度,明确系统的需求,保证系统的稳定性。所述事件是指计算机领域的事件驱动。
如图1,示出本发明一个具体实施例中一种软件模块间的通信方法的整体流程示意图。总体上,包括:
步骤1,获取第一模块的事件发送请求中所包含的标识hash值;
步骤2,利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;
步骤3,利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
在本发明该具体实施例中,为了方便开发者全局方便的调用事件发送方法,将事件发送方法抽象成一个单例类。一个单例类全局有且仅有一个实例,这样就可以确保整个系统只有一个投递事件的实例存在。所设计的事件发送方法利用所在系统中的事件传递函数来进行事件的发送。本具体实施例设计的巧妙的地方就是对事件的发送主要是靠事件本身的标识hash值来进行区分(hash值可以理解为一个类的唯一标示符)。也就是发送方和接收方不需要建立任何耦合关系,我们事件发送系统会根据事件的hash值与订阅者(订阅模块)订阅的hash值进行匹配,如果匹配上了就会将事件发送到订阅者(订阅模块)中去。本具体实施例所述方法在解决各模块直接通信基础上,还能够实现能够实现高耦合低内聚的有益效果。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤1还包括:利用定义为全局单例模式类的事件发送函数,确认第一模块的事件发送请求所包含的事件是否存在于系统订阅事件集合中。
在本发明该具体实施例中,所述步骤1还包括:利用定义为全局单例模式类的事件发送函数,确认第一模块的事件发送请求所包含的事件是否存在于系统订阅事件集合中。本具体实施例中使用了一个集合列表用来维护当前系统中的所有订阅事件。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤1前还包括:在软件中各模块接口函数的参数中添加与所述软件中各模块订阅的各事件相对应的标识hash值。
在本发明该具体实施例中,提供了一种软件模块间的通信方法,所述各模块接口函数通过标识前缀开头且所述函数的参数包含至少一个事件。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述全局单例模式类的事件发送函数以静态格式存储在内存中。
在本发明该具体实施例中,单例模式类由于本身是静态的所以也是存储在静态区中,这样就能够方便其他类方便的进行获取。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤2中调用所述第一模块外其他模块的接口函数中包含所述hash值的事件并发送的步骤进一步包括:在Java中利用invoke方法,将所述第一模块外其他模块的接口函数中包含所述hash值的事件,发送给各包含所述hash值的事件所对应的模块。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤1前还包括:
步骤0,基于系统中各订阅事件的唯一标识,将当前软件中各模块中的订阅事件关联保存在订阅事件集合中。
在本发明该具体实施例中,本方案设计的事件订阅过程为了解耦没有直接使用集合中的add方法来添加订阅事件因为直接add会导致两者之间的强耦合关系对不利于后期软件的维护和扩展。为了能够将事件注册到集合中我们对需要注册的事件添加一个自定义的标签,有了这个标签后我们后续可以通过反射的方式来解析所述自定义标签,从而来找到需要订阅的事件,然后将该事件存放到map集合中。通过上述方案的实施就能够通过低耦合的方式将订阅事件集成到map集合中去了。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤0还包括:将所述订阅事件集合静态存储在内存中。
在本发明该具体实施例中,本方案设计中为了使订阅集合不被系统垃圾回收器进行回收,我们将本map集合设计成为静态的,在申明集合的时候我们需要使用static来进行标记。被申明为静态的集合虚拟机会将其保存到静态区中,静态区内存中的数据在整个应用的申明周期中是不会被销毁的。
在本发明另一个具体实施例中,一种软件模块间的通信方法,所述步骤0还包括:将所述订阅事件集合为map集合。集合列表我们使用的是map集合,使用map集合能够提高后续对接收端的事件查询效率。
在本发明另一个具体实施例中,给出一种软件模块间的通信方法的详细实施例,本具体实施例就Android软件中Fragment间的通信进行说明。
本方案为了解决上述问题特别设计了一套协助Fragment之间通信的一套方法,通过本方案的实施能够高效的在深层次之间的Fragment通信,同时解决了Fragment之间通信时高耦合的技术问题。
本方案的设计重点分为下面几个部分来进行介绍。
整体设计本实施例将按照四个大的方面来进行陈述:接收端对接收事件的订阅、事件发送、反射方式进行事件分发和事件接收。
1、接收端对接收事件的订阅:
本步骤重点在于描述接收端如何将接收事件订阅到本实施例的分发系统的。本方案中使用了一个集合列表用来维护当前系统中的所有订阅事件。集合列表本实施例使用的是map集合,使用map集合能够提高后续对接收端的事件查询效率。
本方案设计中为了使订阅集合不被系统垃圾回收器进行回收,本实施例将本map集合设计成为静态的,在申明集合的时候本实施例需要使用static来进行标记。被申明为静态的集合虚拟机会将其保存到静态区中,静态区内存中的数据在整个应用的申明周期中是不会被销毁的。
本方案设计的事件订阅过程为了解耦没有直接使用集合中的add方法来添加订阅事件因为直接add会导致两者之间的强耦合关系对不利于后期软件的维护和扩展。为了能够将事件注册到集合中本实施例对需要注册的事件添加一个自定义的标签@RegisterTarget,有了这个标签后本实施例后续可以通过反射的方式来解析@RegisterTarget从而来找到需要订阅的事件,然后将该事件存放到map集合中。
通过上述方案的实施本实施例就能够通过低耦合的方式将订阅事件集成到map集合中去了。
2、事件发送:
为了方便开发者全局方便的调用事件发送方法,本实施例将事件发送方法抽象成一个单例类。一个单例类全局有且仅有一个实例,这样就可以确保整个系统只有一个投递事件的实例存在。单例类由于本身是静态的所以也是存储在静态区中,这样就能够方便其他类方便的进行获取。
本实施例所设计的事件发送方法函数非常简单就是post(event)来进行事件发送。本方案设计的比较巧妙的地方就是对事件的发送主要是靠event本身的hash值来进行区分(hash值可以理解为一个类的唯一标示符)。也就是发送方和接收方不需要建立任何耦合关系,本实施例事件发送系统会根据event的hash值与订阅者订阅的hash值进行匹配,如果匹配上了就会将事件发送到订阅者中去。
通过上述介绍,本步骤主要是为了方便事件的发送所以设计成单例来获取事件的发送实例然后使用post方法来将事件分发出去。
3、反射方式进行事件分发:
为了解耦事件发送、事件接收和事件分发总线之间的关联性,本方案对事件的分发使用了反射的方式来进行实施。
解耦事件总线和事件订阅之间的关系是通过反射方式来查找订阅事件并将订阅事件保存到map总线上。
具体是通过调用虚拟机提供的Class.forName的方式来加载某一个类,加载一个类后系统会返回一个class对象A,然后本实施例通过调用A对象中的GetMethod函数来反射出具体的订阅方法,然后通过invoke来执行反射的方法。这样本实施例就可以将订阅事件保存到map总线中了。这样就通过低耦合的方式保存了事件的订阅到map总线中。事件map中对事件的保存时通过键值对来进行保存的,本实施例在对订阅事件的保存的时候将键设置为事件的hash值,值设置为事件对象本身。这样后期本实施例来对事件分发的时候就能够通过hash值来快速查询事件对象了。
当一个事件发送到事件总线上的时候本实施例首先通过getHash方法得到事件的hash值,然后拿到该hash值在map集合中查询是否存在该hash值的事件。如果查询到该事件说明本实施例有订阅者订阅过该事件,此时本实施例就需要找到订阅者的具体位置。
为了方便本实施例查询订阅者的具体位置本实施例规定事件订阅者的接收函数一定是以receiveEvent前缀开头的函数并且参数就是事件本身的一个函数。
这样本实施例来对事件进行分发的时候本实施例可以通过Class.forName的方式来加载某一个类,然后调用getMethods方法来获取这个类中的所有方法集。然后再对该方法集进行遍历判断每一个方法是否以receiveEvent开头如果是的说明该方法就是本实施例的订阅事件。然后再通过调用getParam方法来判定该方法的参数,获取到参数后再通过调用gethash来得带该参数的hash值。本实施例再进一步判定该hash值是不是和本实施例事件的hash值一致,如果是一致的说明这个函数就是本实施例需要分发到事件的函数对象了。
本实施例就可以通过反射中的invoke方法来反射的方式调用该函数同时将事件传递到该函数中。这样就完成了一次事件的分发过程。
本实施例在通过上述所述的反射方式来调用事件的接收函数,将最终的事件分发到接收端。(事件的订阅和分发均使用反射的方式来实现),这样就完美的解决了之间的耦合关系。
4、事件接收:
事件的接收由于和事件分发总想是隔离的所以本实施例对事件接收这段进行了硬性规定必须以receiveEvent的前缀开头并且该函数的参数必须是一个event事件。这样后期本实施例才能够通过上述所述的方法找到事件接收的地方然后将事件分发到该处来。
也就是通过我么自定义的规则来建立起之间的联系的,这样处理的好处是能够解耦事件分发和接受之间的耦合关系。这样就能够提高软件系统的扩展和维护性。
本具体实施例设计了一套低耦合的事件订阅和发送方法,通过使用本方案所述的方法能够有效的解决深层级Fragment之间的消息通信的问题。避免了传统通信中需要多层级传递的问题,通过反射有效的解耦之间的耦合关系使得整个系统具有更强的扩展性和可维护性。
在本发明另一个具体实施例中,一种软件模块间的通信系统,包括请求获取模块A1、函数获取模块A2和事件发送模块A3:
所述请求获取模块A1,用于获取第一模块的事件发送请求中所包含的标识hash值;
所述函数获取模块A2,用于利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;
所述事件发送模块A3,用于利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
在本发明另一个具体实施例中,一种软件模块间的通信系统,所述请求获取模块还用于:利用定义为全局单例模式类的事件发送函数,确认第一模块的事件发送请求所包含的事件是否存在于系统订阅事件集合中。
在本发明另一个具体实施例中,一种软件模块间的通信系统,还包括hash模块,用于在软件中各模块接口函数的参数中添加与所述软件中各模块订阅的各事件相对应的标识hash值。
在本发明另一个具体实施例中,一种软件模块间的通信系统,所述各模块接口函数通过标识前缀开头且所述函数的参数包含至少一个事件。
在本发明另一个具体实施例中,一种软件模块间的通信系统,所述全局单例模式类的事件发送函数以静态格式存储在内存中。
在本发明另一个具体实施例中,一种软件模块间的通信系统,所述函数获取模块还用于:在Java中利用invoke方法,将所述第一模块外其他模块的接口函数中包含所述hash值的事件,发送给各包含所述hash值的事件所对应的模块。
在本发明另一个具体实施例中,一种软件模块间的通信系统,还包括订阅模块,用于将所述订阅事件集合静态存储在内存中。
在本发明另一个具体实施例中,一种软件模块间的通信系统,将所述订阅事件集合为map集合。
图3是示出本申请实施例的利用上述所有实施例中所述的软件模块间的通信方法的设备的结构框图。
参照图3,所述WDM-FSO网络节点资源共享方法的测试设备,包括:处理器(processor)301、存储器(memory)302、通信接口(Communications Interface)303和总线304;
其中,
所述处理器301、存储器302、通信接口303通过所述总线304完成相互间的通信;
所述通信接口303用于该测试设备与软件模块间的事件路由的通信设备之间的信息传输;
所述处理器301用于调用所述存储器302中的程序指令,以执行上述各方法实施例所提供的方法,例如包括:步骤1,获取第一模块的事件发送请求中所包含的标识hash值;步骤2,利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;步骤3,利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
本实施例公开一种计算机程序产品,所述计算机程序产品包括存储在非暂态计算机可读存储介质上的计算机程序,所述计算机程序包括程序指令,当所述程序指令被计算机执行时,计算机能够执行上述各方法实施例所提供的方法,例如包括:步骤1,获取第一模块的事件发送请求中所包含的标识hash值;步骤2,利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;步骤3,利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
本实施例提供一种非暂态计算机可读存储介质,所述非暂态计算机可读存储介质存储计算机指令,所述计算机指令使所述计算机执行上述各方法实施例所提供的方法,例如包括:步骤1,获取第一模块的事件发送请求中所包含的标识hash值;步骤2,利用定义为全局单例模式类的事件发送函数,获取所述第一模块外其他模块的接口函数,获取包含所述标识hash值的接口函数;步骤3,利用定义为全局单例模式类的事件发送函数,将所述第一模块的事件发送请求中所包含的事件发送给包含所述标识hash值的接口函数所在的模块。
本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,前述的程序可以存储于一计算机可读取存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:ROM、RAM、磁碟或者光盘等各种可以存储程序代码的介质。
以上所描述的软件模块间的通信方法的设备等实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性的劳动的情况下,即可以理解并实施。
通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到各实施方式可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件。基于这样的理解,上述技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在计算机可读存储介质中,如ROM/RAM、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行各个实施例或者实施例的某些部分所述的方法。
最后,本申请的方法仅为较佳的实施方案,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。