抽象的设备管理框架

本文由 @lonelyrains 出品,转载请注明出处。 
文章链接: http://blog.csdn.net/lonelyrains/article/details/45243671


最近在弄一个公司的设备管理框架,发现可以把设备抽象出来,对其他可能的设备也可能用这一套框架。出于保密原则,删除了公司业务相关的信息,就列出来如下。

DevTool模块



1 程序描述

DevManager简称DM,ViewManager简称VM。程序启动后,DevManager内注册对Controller的事件处理回调eventCallbackForDM,以便Dev事件到来时回调;ViewManager内注册对Controller的事件处理回调eventCallbackForVM,以便UI事件到来时回调。
eventCallbackForDM内调用dispatchRequestFromCfg解析是否有匹配的事件对应的需求需要处理,如果有而且需要界面,则调用getDataFromDMtoVMForView从DevManager中获取对应界面需要的相应数据,并调用ViewManager的回调requestCallback处理对应的UI请求,最终弹出UI。UI处理完之后,调用eventCallbackForVM,通知Controller对应UI的完成事件,并将UI的返回数据保存在Controller内,然后Controller内调用getDataFromVMtoDMForDev组织数据,调用DevManager的requestCallback请求,最终调用DevApi更新Dev内数据。如果需要提示操作结果,还需要经历一次DM-Controller->VM->Controller的操作。
上述描述是针对Dev事件处理的,也有来源于用户操作的处理。如果是类似修改名称的操作,处理顺序为VM->Controller->DM->Controller->VM-> Controller。
1) VM先启动主页面,响应用户按钮请求,修改名称是在VM内弹框;
2) 填完Dev名称,合法验证通过后,Controller获取数据形成Dev的Request;
3) DM内调用封装好的DevApi实现修改名称,成功之后,返回给Controller;
4) Controller发送UI的Request,说明修改名称成功;
5) VM弹出修改成功提示,用户点击成功;
6) VM通知Controller确认成功。
在5)用户点击成功之前,如果此时用户断开Dev,而且用户需求中要求断开Dev之后关闭相关的对话框,将从DM->Controller->VM完成一次关闭提示框的操作。
在DM和VM之间加一层Controller的好处是所有需要配置定制的部分全部在此部分完成,其他实现可以以库的形式提供。
抽象一层Controller,还有一个好处,是不用在VM内缓存任何数据。比如想实现一个下拉框选择Dev,仅仅有连接/断开事件时传Dev指针到VM内是不够的,需要VM自己维护已有的Dev列表。
UML静态图如下:

 抽象的设备管理框架_第1张图片


2 功能

DevManager、ViewManager 分别实现设备管理、视图管理。主程序内实现控制器的功能,连接各个模块,实现消息的传递、客户定制需求的处理。

2.1 设备管理

连接Dev则新建Dev对象存入devMap,所有针对Dev的数据操作都由DevManager进行。除了与Dev通信,还要负责回复Controller的请求数据、调用Controller的回调,通知Controller事件来了。

2.2 视图管理

响应Conroller的请求弹出UI,当UI操作结束时,调用Controller的回调返回UI操作的结果。

2.3 控制器

Conroller提供回调函数给DevManager、ViewManager,以响应事件,并实现对配置的解析,针对当时的事件,生成相应的请求,提交给DevManager和ViewManager。

2.4 性能



2.5 输入项



2.6 输出项

无。

2.7 算法

无。

2.8 流程逻辑

无。

2.9 接口

数据传输统一采用XML格式,如果某些元素是二进制流数据,且不是无符号整型,也先转成十六进制字符串,然后再传输。

2.9.1 ViewType定义格式

支持的视图类型:View、ListView、TabView、ImageView、Button、ComboBox、TextView、TableView、TrayView、BubbleView、AnimateView。
支持的视图内容布局类型:contentLayout(left/right/center/top/down) marginWidth/marginHeight
支持的布局类型:linearLayout(vertical/horizontal) 
支持的宽高类型:height/width(30%/30)  %方式定义与父窗口的相对位置,纯数字定义与MFC的rc文件中定义单位相同


例如定义一个竖型的管理工具mainView
<?xml version="1.0" encoding="utf-8"?>
<view>
	<viewType>mainView</viewType>
	<width>500</width>
	<height>400</height>
	<IsCenterToDeskTop>true<isCenterToDeskTop>
	<linearLayout orientation = "vertical">
		<linearName>outline</linearName>
		<marginWidth>2%</marginWidth>
		<width>96%</width>
		<height>96%</height>
		
		<!--headline-->
		<linearLayout orientation = "horizontal">
			<linearName>headline</linearName>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>5%</height>
			<backgroundColor>#0001</backgroundColor>
			<imageView>
				<imageName>logoIco</imageName>
				<imageUrl>$(res)/logoIco.png</imageUrl>
				<contentLayout>center</contentLayout>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
			</imageView>
			<textView>
				<marginWidth>2%</marginWidth>
				<width>70%</width>
				<height>96%</height>						 
				<textValue>$(CustomerName)$(DevName)$(ToolName)</textValue>
			</textView>
			<button>
				<id>btn_min</id>
				<action>onMin</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_min.png</imageUrl>
			</button>
			<button>
				<id>btn_max</id>
				<action>onMax</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_max.png</imageUrl>
				<isEnable>false</isEnable>
			</button>
			<button>
				<id>btn_close</id>
				<action>onClose</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_close.png</imageUrl>
			</button>
		</linearLayout>
		
		<!--logo long-->
		<imageView>
			<imageName>logoLong</imageName>
			<imageUrl>$(res)/logoLong.png</imageUrl>
			<contentLayout>center</contentLayout>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>30%</height>
		</imageView>
		<textView>
			<marginWidth>2%</marginWidth>
			<width>70%</width>
			<height>50%</height>
			<textValue>$(CustomerName)$(DevName)$(ToolName)</textValue>
		</textView>
		<linearLayout orientation = "horizontal">
			<linearName>headline</linearName>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>56%</height>
			
			<!--logo-->
			<listView>
				<id>listView_mainView</id>
			</listView>
			
			<!--btnlist-->
			<linearLayout orientation = "vertical">
				<linearName>btnList</linearName>
				<marginWidth>2%</marginWidth>
				<width>36%</width>
				<height>56%</height>
				<button>
					<id>btn_change_name</id>
					<action>onChangeName</action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
				<button>
					<id>btn_view_devinfo</id>
					<action>onView devinfo </action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
				<button>
					<id>btn_init</id>
					<action>onInit</action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
			</linearLayout>
		</linearLayout>
	</linearLayout>
</view>




2.9.2 DM->Controller交互事件数据格式

<?xml version='1.0' encoding='utf-8'?>
<event>
	<eventType>connect</eventType>
	<devIndex>3</devIndex>
</event>




eventType可选择connect/disconnect/format/datachange
在Controller的eventCallbackForDM中调用。


然后Controller调用getDatatFromDMtoVMForView,组织下一小节中描述的Controller->VM交互请求数据。


mapToUIId标签实现从数据到UI填充的映射。

2.9.3 Controller->VM交互请求数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>createUI</requestType>
	<view>
		<viewType>mainView</viewType>
		<viewId>view_1</viewId>
		<viewParentId>desktop</viewParentId>
		<devList> 
			<!—此处的id与viewType定义中的控件对应的id相同,表示填充到对应的id里-->
			<id>devList</id>
			<mapToUIId>listView_mainView</mapToUIId>
			<selectedId>dev_1</selectedId>
			<dev>
				<id>dev_1</id>
				<name>DevStd</name>
				<sn>DS20150415</sn>
				<imageUrl>$(res)/dev.png</imageUrl>
				<otherParamList>
				<param1>
				  <id>param_1</id>
				  <imageUrl>$(res)/param1.png</imageUrl>
				  </param1>
				<param2>
				  <id>param_2</id>
				  <imageUrl>$(res)/param2.png</imageUrl>
				  </param2>
				</otherParamList >
			</dev>
		</devList>
		<button>
			<id>btn_change_name</id>
			<isEnable>true</isEnable>
		</button>
		<button>
			<id>btn_view_devinfo</id>
			<isEnable>true</isEnable>
		</button>
		<button>
			<id>btn_init</id>
			<isEnable>true</isEnable>
		</button>
	</view>
</request>




requestType可以是一些已在概要设计里归纳需要实现的需求,比如createUI、closeUI、showUI、hideUI、updateUI。updateUI中对应的是viewId。当且仅当是createUI需要viewType、viewParent、devId。createUI的返回参数有一个是viewId。
该数据格式在VM的requestCallback中调用。


2.9.4 VM->Controller交互事件数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateUI</requestType>
	<view>
		<viewType>mainView</viewType>
		<viewIndex>view_1</viewIndex >
		<event>click</event >
		<listView>
			<id>listView_mainView</id>
			<selectedId>param_2</selectedId>
		</listView>
	</view>
</request>






用户点击了listView的证书节点。
该数据格式在DM的eventCallbackForVM中调用。


用户选择了证书,则提交请求使能证书操作相关按钮。Controller->VM的请求在VM的requestCallback中调用,格式如下:

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateUI</requestType>
	<view>
		<viewId>1</viewId>
		<viewType>mainView</viewType>
		<button>
			<id>btn_view_param2</id>
			<isEnable>true</isEnable>
		</button>
	</view>
</request>






用户点击了修改名称按钮。则调用一次VM->Controller的交互事件,声明按钮动作,Controller再提交一次到VM的交互请求:


<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>createUI</requestType>
	<view>
		<viewType>changeLabelView</viewType>
		<viewId>view_2</viewId>
		<devList>
			<dev>
				<name>dev1</name>
				<id>dev1_devStd</id>
				<value>devStd</value>
				<mapToUIId>oldName</mapToUIId>
				</label>
				<sn>
				<id>DS20150415<id>
				<mapToUIId>sn</mapToUIId>
				</sn>
			</dev>
		</devList>
	</view>
</request>




用户点击了changeNameView的OK之后,调用一次VM->Controller的交互事件,正式调用修改名称操作。


2.9.5 Controller->DM的交互请求数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateDev</requestType>
	<dev>
		<id>dev1_devStd</id>
	</dev>
	<action>changeName</action>
	<paramList>
		<oldName>devStd</oldName>
		<newName>devStdNew</newName>
	</paramList>
</request>


该消息在DM的requestCallback中调用。
requestCallback处理完之后,如果执行成功,Controller再发一次到VM的更新消息,改变UI显示的Name,并创建一个提示框,提示成功。




3 补充说明:

1、同步异步调用的实现区别:
同步:调用者会等待回调结束之后做下一步操作。
异步:调用者请求之后,马上返回。如果有更新的结果,则以事件方式通知Controller。完全不需要在调用者和被调用者创建新的线程来检测。这样做的要求是要在同一进程里。
如果非得是不同进程,可以考虑实现一种RPC远程过程回调。但是目前来看,从之前讨论过的安全性问题来看,应该尽量做到同一进程,然后UI以库形式调用。


2、UI中定义的按钮响应函数处理方法:
所有的按钮功能在Controller中定义,比如修改名称,按照字符串匹配查找相应的函数指针,并填充相应的参数列表。可以统一所有的参数均为字符串。


3、UI中的隐藏:通过Width或者Height更新为0%即可。


至此,可以统一所有的UI请求,不论是不是管理工具发出的,或者即使是安装包的UI,都可以按照这一套来做,完全解耦。全部用XML定义。


你可能感兴趣的:(抽象的设备管理框架)