国内某二线城市某科技公司,项目、产品繁多,软硬件通吃。硬件大牛H,软件新人S,研发BOSS:编程
H:BOSS,这两天刚刚搞出个采集电参数的模块,能不能安排人作个简单的测试程序,就是一个串口,电脑上看一下数据就行,很简单的;网络
BOSS:能够,小S,你把老H这个功能实现下,在我原来的那个XXX串口程序基础上改一下就好了;框架
S:我在整个网站,没时间呀?ide
BOSS:这个简单,改一下显示就好了;函数
S:行,听你的(无奈!!)测试
而后S把BOSS原来的程序COPY一份,开改打开串口--->收数据---->分析数据--->显示--->关闭串口,丫的还要改程序名字等等网站
...this
X月事后:spa
H:BOSS,我整了个XX控制器,须要用电脑软件控制一下就行,就发两个控制指令,而后看到控制结果就行,很简单的;线程
BOSS:老H,你干的不错呀,小S,你有空把这个控制实现一下,就在你上次那个采集程序基础上改一下就好了;
S:我上次那网站还没整完呀?客户吹的紧呀?
BOSS:这个简单,就两个控制指令,算你半天工做量
S:(心里:简单?简单$%$$####%^)
而后S把原来的采集程序COPY一份,开改打开串口--->发控制指令--->收数据---->分析数据--->显示--->关闭串口,丫的还要改程序名字等等
...
又是X月事后:
H:BOSS呀,有个客户那边说咱们的协议很差使,要用国标的协议,能不能把协议稍微改一下,很简单的;
BOSS:嗯,客户第一嘛,小S,耶...小S...小S...小S...小S...
S:老大,我是真没空呀,让老H本身改吧,很简单的,把XX工程打开,改XX文件XX行
H:......
搞硬件的老H能改?他知道显示界面怎么委托?开玩笑,他可能都不知道什么是类;
还有为何总是拿之前的程序来改?由于咱们须要之前的串口读写程序,新写的话太费时间,你说我能够封装好点,让别人调用方便点,那仍是得调用呀,若是换成网络TCP怎么办?再换成其余的怎么办?
咱们对底层依赖的太严重了!咱们应该把这种依赖倒置(小S:不就是依赖倒置嘛,切!!BOSS:#@¥%,理论害死人呀,你丫知道你不实践)。咱们要作一个平台,不管什么协议,不管什么串口、网络,甚至其它通讯方式,还有WINFORM界面显示我都把它预先处理好,让只会简单C语言的老H只关心他知道的协议; 因而就出现下面这个框架:
绿色表示原始数据包的流向状况,平台本身处理全部与硬件通讯功能,全部的协议放在模块中用户本身处理。
平台完成开发后,提供一个接口定义的模块,好比下面这个接口:
namespace IDataMonitor { public abstract class DllBase { /// <summary> /// 接收数据处理函数 /// </summary> /// <param name="buffer">收到的原始数据</param> /// <returns>返回一个字符串,用于采集平台界面显示</returns> public abstract string OnReceive(byte[] buffer); /// <summary> /// 模块加载的时候执行,禁止在该函数里编写长时间执行的代码,若是须要能够用线程代替 /// </summary> public abstract void DllLoad(); /// <summary> /// 在主程序退出时执行 /// </summary> public abstract void DllUnload(); /// <summary> /// 能够经过该委托发送查询/控制指令 /// </summary> public Func<byte[], bool> SendFunc; } }
公司内部或其余公司开发人员拿到接口定义模块后,就能够基于它开发完成本身的协议模块(DLL形式),而后放置在平台指定的文件夹下便可,无需再次修改数据通讯平台的代码,真正实现公司数据采集平台的通用。
平台搭建完成后,老H只须要新建一个类库工程,添加接口文件的引用,而后以下处理本身的协议便可:
namespace TestDll { public class Class1 : DllBase { private volatile bool _bListen = true; public override string OnReceive(byte[] buffer) { //这里测试,原包返回 return Encoding.Default.GetString(buffer); } public override void DllLoad() { var thread = new Thread(Query); thread.Start(); } public override void DllUnload() { _bListen = false; } public void Query() { while (_bListen) { string test = "this datas come from test dll"; SendFunc(Encoding.Default.GetBytes(test)); Thread.Sleep(1000); } } } }
而后老H把生成的DLL文件放置在平台运行文件夹下,简单配置一下对应的具体网络(或串口):
我为了方便,把测试的串口和网络都对应到TestDll处理了,运行的效果以下:
经过代码能够看出,无需了解任何winform、TCP或串口编程知识,甚至能够不用知道什么是TCP,什么是串口,只须要把收到的数据解析出来就好了。小S泪流满面,BOSS清静了!!
平台主文件DataMonitor工程及相关的接口测试:https://datamonitor.codeplex.com/