前面的几篇博文对模块如何应对下层接口变化和方案商变化做了设计,然而,模块怎么良好地和Android层的应用交互,这个需要怎么设计呢?考虑到我们的应用通过Dongle模块和底层交互实现一些功能,上层发送指令,要求Dongle模块做某件事情即可。二者可以用命令模式来交互.
总图是这样子,我们设计需要达到的目的:
1.方案商层面的变化(方案商增加,方案商减少,方案商的实现逻辑发生变化)。
2.要能够应付模块层的变化(模块增加,模块减少,模块实现逻辑发生变化),
这里我们着重看下新增加的命令模式,对App和模块层交互的影响:
首先看下初版的代码:
1.m测试代码:
cout << "test begin.." << endl;
ModuleControl *moduleControl = new ModuleControl();
//先创建一个方案商工厂,专门用来创建方案商
SolutionProviderFactory *factory = new SolutionProviderFactory();
DongleModule *dongleModule = new DongleModule(factory);
DongleModuleCommand dongleModuleCommand(*dongleModule);
moduleControl->SendCommand(&dongleModuleCommand);
cout << "test end..." << endl;
当执行: moduleControl->SendCommand(&dongleModuleCommand);的时候:
2.执行cmd的execute函数
void ModuleControl::SendCommand(Command *cmd)
{
cout<<"ModuleControl::SendCommand(Command cmd)..."<<endl;
command = cmd;
command->execute();
}
3.而这个cmd是DongleModuleCommand类型,所以最后调用到的是:
bool DongleModuleCommand::execute()
{
//在这里确定传递的方案商参数是否合适?
cout<<"DongleModuleCommand::execute() excuting!!!!!!!!!!!!"<<endl;
dongleModule.BurnDongle(1);
return true;
}
4.
这里,如果要执行一个模块行为,我们就必须为这个模块
这个时候我们会发现这个命令模式是有问题的。简单的命令模式是让请求者和接收者之间解耦,如果我们的app需要做的功能是:
操纵某个模块而不是操纵某个模块的某个方法。那么这样将模块构建成命令打包发送过去,就OK了。
然而我们的需求恰恰是应用要操纵某个模块的某个方法。所以只是将模块打包成命令发送过去是不行的,还需要一些参数才行。
比如,这里bool DongleModuleCommand::execute()不带参数的话,就只能指定一种行为。因此这里需要作更改,可能还需要参数。
先前的设计,是将模块,比如DongleModule的一个大功能的接口,比如BurnDongle直接暴露给应用,然后app层的应用调用这些接口去完成功能取得返回值就OK了。
然而,如果有这种需求:现在有一个新功能,需要利用到和BurnDongle平级的好几个接口来实现一个新功能,那么就要重新设计一层封装?,这个后续再考虑。