[連載]《C#通訊(串口和網絡)框架的設計與實現》- 7.外部接口的設計


目       錄

第七章           外部接口的設計... 2

7.1           插件接口... 2

7.2           圖形顯示接口... 3

7.3           數據導出接口... 5

7.4           服務組件接口... 6

7.5           插件管理器... 8

7.6           框架整合、重構... 9

7.7           小結... 10

第七章     外部接口的設計

開發者不僅可以二次開發設備驅動,還可以二次開發自定義圖形顯示形式、

自定義數據導出格式和多種業務服務,並且設備驅動接口與這三種接口進行事件響應和數據交互。

7.1    插件接口

    圖形顯示接口、數據導出接口和服務組件接口都繼承自統一的插件接口(IPlugins),主要是方便管理和擴展。插件接口的代碼定義如下:

public interface IPlugins : IDisposable
{
       /// <summary>
       /// 服務Key,要求唯一
       /// </summary>
       string ThisKey { get; }

       /// <summary>
       /// 服務名稱
       /// </summary>
       string ThisName { get; }

       /// <summary>
       /// 更新設備數據,用於接收來自設備驅動的數據信息
       /// </summary>
       /// <param name="devid">設備ID</param>
       /// <param name="obj">設備對象</param>
       void UpdateDevice(int devid, object obj);

       /// <summary>
       /// 移除設備,當框架平台刪除設備的時候進行響應。
       /// </summary>
       /// <param name="devid">設備ID</param>
       void RemoveDevice(int devid);
}

     圖形顯示接口、數據導出接口和服務組件接口與插件接口的繼承關系如下圖:

 

     設備驅動只要有更新數據就會通過事件把數據傳送到UpdateDevice接口里,這個接口內部到底怎么處理完全由二次開發者來決定。當觸發設備驅動的刪除事件,就會調用RemoveDevice接口,以刪除、釋放資源。

7.2    圖形顯示接口

    框架平台通訊設備驅動把數據采集上來的只是原始數據,經過處理后要形成業務數據,那么就會有顯示、分析、查詢、打印、報表等業務功能,並且針對同樣的數據信息,不同的用戶要求處理的方式有很大的不同。這部分功能變動很大,但是又不能每次有變動就要去修改框架平台,因為框架是“穩定”的部分,形成版本控制后就不隨便改變了。

   基於這樣考慮,作為框架要提供一個機制,能夠加載二次開發者設計的UI窗體。用於顯示采集終端設備的數據,可以把不同類型設備的數據以多種形式集成顯示在不同界面上。方便為用戶提供多種的、更友好的人機交互界面。

   首先,框架平台不能在啟動的時候就顯示所有UI窗體,具體要顯示哪個UI窗體完全由用戶自己決定,所以,我們要通過配置文件的形式把二次開發的組件信息加載到菜單里,提供可觸發的顯示事件入口,如下圖:

 

   其次,那么以什么樣的形式顯示窗體呢?像很多管理系統一樣,我們采用Form Tab的方式顯示,如下圖:

 

   UI部分的設計就這樣了,但是從業務角度我們要考慮兩件事:(1)在二次開發的窗體上單擊鼠標右鍵事件時要顯示相應設備的上下文菜單,也就是說要調用IRunDevice設備驅動的ShowContextMenu函數,要在IGraphicsShow接口中提供MouseRightContextMenuHandler事件,以驅動調用ShowContextMenu函數顯示上下文菜單。(2)當單擊菜單項的時候,會以Tab的形式顯示窗體,但是當多次單擊后是不能多次顯示UI窗體的,所以要有一個管理器(GraphicsShowController),通過接口的ThisKey屬性判斷當前顯示的UI窗體是否存在,如果不存在,那么就顯示該UI窗體,否則退出操作;既然有一個管理器,當關閉窗體的時候,需要把該UI窗體實例從管理器中刪除掉,避免無法再次顯示窗體,因為它一直存在於管理器中。所以還需要在接口中定義一個關閉窗體的事件GraphicsShowClosedHandler,釋放窗體資源后從管理器中刪除實例。

   至此,自定義窗體顯示部分就設計完畢了,IGraphicsShow接口定義代碼如下:

public interface IGraphicsShow : IPlugins
{
       /// <summary>
       ///    關閉窗體事件時發生
       /// </summary>
       event GraphicsShowClosedHandler GraphicsShowClosedHandler;
 
       /// <summary>
       ///     單擊右鍵
       /// </summary>
       event MouseRightContextMenuHandler MouseRightContextMenuHandler;
}

7.3    數據導出接口

    在數據集成系統項目中,要么是集成其他廠家的設備數據,要么是其他廠家集成自己家的設備數據,在沒有統一的標准前提下,會有各種集成數據的格式。為了滿足此類的場景,為設備導出數據專門設計了接口,開發者可以繼承該接口,設備在處理完數據后,會把數據自動傳輸到該接口,可以按規定的數據格式進行輸出了。

     對設備驅動實時數據導出,可以把一類的設備數據導出成多種數據格式。

     導出數據插件可以通過配置文件進行加載,只要設備驅動有數據更新,就把數據通過事件傳遞給導出數據接口。不在配置文件中配置插件信息,則程序不進行加載,不進行導出操作。所以,這種事務性的服務不需要界面來完成,可以在宿主程序啟動時通過代碼來完成。

    IExportData數據導出接口代碼定義如下:

public interface IExportData:IPlugins
{
       /// <summary>
       /// 格式化數據
       /// </summary>
       /// <param name="devid"></param>
       /// <param name="obj"></param>
       /// <returns></returns>
       object FormatDataString(int devid, object obj, DeviceType devicetype);
}

7.4    服務組件接口

     圍繞着設備驅動模塊采集的數據,根據應用場、需求,可以提供多種應用服務,例如:數據轉發服務、4-20mA服務、短信服務、LED服務、OPC服務、以及復雜的實時數據分析服務等。在保障數據實時性、穩定性的前提下,服務接口可以提供統一的服務機制,方便開發者進行二次開發。

     服務插件的服務方式,這種服務是長期運行的事務性任務,所以更復雜一些。

    有些服務需要隨宿主程序啟動而自動運行,有些服務需要人工手動啟動才運行。在宿主程序啟動的時候通過配制文件要把服務的信息加載到菜單上,菜單里顯示的服務可能有些已經啟動了;有些需要通過單擊操作,顯示窗體並填寫必要的信息后才可能啟動。所以,宿主程序與服務插件不是單向交互,而是雙向數據、事件交互。

    IappService服務接口在IPlugins基礎上進行擴展,增加了函數、屬性和事件,代碼定義如下:

public interface IAppService : IPlugins
{
        /// <summary>
       ///     啟動服務
       /// </summary>
       void StartService();

       /// <summary>
       ///     是否自動啟動
       /// </summary>
       bool IsAutoStart { set; get; }
      
         /// <summary>
       ///     服務類型
       /// </summary>
       ServiceType ServiceType { set; get; }

       /// <summary>
       ///     單擊事件,關聯菜單
       /// </summary>
       void OnClick();

       /// <summary>
       ///     釋放服務
       /// </summary>
       void ReleaseService();

       /// <summary>
       ///     寫日志事件
       /// </summary>
       event WriteLogHandler WriteLogHandler;
}

(1)    StartService函數:當服務的啟動方式(IsAutoStart)為"自動啟動"的時候,框架平台在加載服務的時候,會自動調用這個接口函數,表示對服務進行啟動操作。

(2)    IsAutoStart屬性:服務啟動類型,標識是否隨框架平台啟動而自動啟動,也就是標識是否會調用StartService接口函數。

(3)    ServiceType屬性:服務類型分為:顯示模式和隱藏模式。顯示模式的服務會在框架平台的菜單上加載以ThisName標識的服務名稱;隱藏模式不會在框架平台的菜單中加載服務名稱,可以把此類服務的IsAutoStart屬性設置為自動啟動,框架平台啟動后自動啟動服務。代碼定義如下:

public enum ServiceType
{
    [EnumDescription("顯示模式")]
    Show = 0x00,
    [EnumDescription("隱藏模式")]
    Hide = 0x01
}

(4)    OnClick事件函數:當服務類型ServiceType為“顯示模式“的時候,服務名稱會被加載到菜單中,當單擊服務菜單項的時候,會調用相應服務的OnClick接口函數,可以在這個接口函數里調用窗體。

(5)    ReleaseService函數:當關閉框架平台和人工手動停止服務后,可以通過這個函數釋放服務資源。

 另外,對於服務組件接口還涉及到服務狀態,標識服務在運行的過程中處

於什么階段,例如:服務正在啟動、服務已經啟動、服務正在運行、服務正在終止、服務已經終止等等。因為根據服務的事務復雜度不同,服務的狀態也可能不同,所以服務狀態的定義交給了二次開發者自己定義。

7.5    插件管理器

    圖形顯示接口、數據導出接口和服務組件接口都分別有一個接口管理器,負責對各功能接口進行管理,它們都繼承自IBaseManager<TKey, TValue>接口。繼承關系圖如下:

 

7.6    框架整合、重構

    總的來說,框架平台涉及到四個主要的接口:IRunDevice設備驅動接口、IGraphicsShow圖形顯示接口、IExportData數據導出接口和IAppService服務組件接口。它們現在的繼承結構關系如下圖:

 

實際上繼承這四個接口二次開發的模塊都是以插件的形式加載到框架平台,框架平台在結構上實現了一整套的運行機制。對上面的繼承關系結構圖進行分析,還有整合、重構的余地,進一步明晰接口關系、整合代碼,提高框架的可擴展性,計划重構后的接口繼承關系如下圖:

 

     所有可擴展的接口都繼承自一個插件接口,再分支出來其他的業務功能接口,類似於C#語言中所有實體都繼承自Object一樣。

7.7    小結

    框架內部實際上是對接口進行直接調用,接口與接口之間的配合又實現了一套協調機制,從而逐步實現了一個框架平台。作為接口實際上是實現了二次開發與框架平台對接的一種形式,並保證在框架平台的協調機制中實現特定的業務功能。所以,任何框架,從頂層來看都是對接口的設計。

 

作者:唯笑志在

mail:504547114@qq.com

QQ:504547114

.NET開發技術聯盟:54256083

文檔下載:http://pan.baidu.com/s/1pJ7lZWf

官方網址:http://www.bmpj.net


免責聲明!

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



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