通用數據采集平台,從架構到代碼


需求場景還原

國內某二線城市某科技公司,項目、產品繁多,軟硬件通吃。硬件大牛H,軟件新人S,研發BOSS:

H:BOSS,這兩天剛剛搞出個采集電參數的模塊,能不能安排人做個簡單的測試程序,就是一個串口,電腦上看一下數據就行,很簡單的;

BOSS:可以,小S,你把老H這個功能實現下,在我原來的那個XXX串口程序基礎上改一下就行了;

S:我在整個網站,沒時間呀?

BOSS:這個簡單,改一下顯示就行了;

S:行,聽你的(無奈!!)

然后S把BOSS原來的程序COPY一份,開改打開串口--->收數據---->分析數據--->顯示--->關閉串口,丫的還要改程序名字等等

...

X月過后:

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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM