通用數據採集平臺,從架構到代碼

需求場景還原

國內某二線城市某科技公司,項目、產品繁多,軟硬件通吃。硬件大牛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/

相關文章
相關標籤/搜索