目 錄
第七章 外部接口的設計... 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:[email protected]
QQ:504547114
.NET開發技術聯盟:54256083
文檔下載下傳:
http://pan.baidu.com/s/1pJ7lZWf官方網址:
http://www.bmpj.net