亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入數(shù)據(jù)驅(qū)動(dòng)編程之表驅(qū)動(dòng)法的詳解

 更新時(shí)間:2013年05月23日 16:33:45   作者:  
本篇文章是對(duì)表驅(qū)動(dòng)法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
數(shù)據(jù)驅(qū)動(dòng)編程之表驅(qū)動(dòng)法 本文示例代碼采用的是c語(yǔ)言。
之前介紹過(guò)數(shù)據(jù)驅(qū)動(dòng)編程《淺談:什么是數(shù)據(jù)驅(qū)動(dòng)編程的詳解》。里面介紹了一個(gè)簡(jiǎn)單的數(shù)據(jù)驅(qū)動(dòng)手法。今天更進(jìn)一步,介紹一個(gè)稍微復(fù)雜,更加實(shí)用的一點(diǎn)手法——表驅(qū)動(dòng)法。
關(guān)于表驅(qū)動(dòng)法,在《unix編程藝術(shù)》中有提到,更詳細(xì)的描述可以看一下《代碼大全》,有一章專(zhuān)門(mén)進(jìn)行描述(大概是第八章)。
簡(jiǎn)單的表驅(qū)動(dòng):
淺談:什么是數(shù)據(jù)驅(qū)動(dòng)編程的詳解》中有一個(gè)代碼示例。它其實(shí)也可以看做是一種表驅(qū)動(dòng)手法,只不過(guò)這個(gè)表相對(duì)比較簡(jiǎn)單,它在收到消息后,根據(jù)消息類(lèi)型確定使用調(diào)用什么函數(shù)進(jìn)行處理。
復(fù)雜一點(diǎn)的表驅(qū)動(dòng):
考慮一個(gè)消息(事件)驅(qū)動(dòng)的系統(tǒng),系統(tǒng)的某一模塊需要和其他的幾個(gè)模塊進(jìn)行通信。它收到消息后,需要根據(jù)消息的發(fā)送方,消息的類(lèi)型,自身的狀態(tài),進(jìn)行不同的處理。比較常見(jiàn)的一個(gè)做法是用三個(gè)級(jí)聯(lián)的switch分支實(shí)現(xiàn)通過(guò)硬編碼來(lái)實(shí)現(xiàn):
復(fù)制代碼 代碼如下:

switch(sendMode)
{
 case:
}
switch(msgEvent)
{
 case:
}
switch(myStatus)
{
 case:
}

這種方法的缺點(diǎn):
1、可讀性不高:找一個(gè)消息的處理部分代碼需要跳轉(zhuǎn)多層代碼。
2、過(guò)多的switch分支,這其實(shí)也是一種重復(fù)代碼。他們都有共同的特性,還可以再進(jìn)一步進(jìn)行提煉。
3、可擴(kuò)展性差:如果為程序增加一種新的模塊的狀態(tài),這可能要改變所有的消息處理的函數(shù),非常的不方便,而且過(guò)程容易出錯(cuò)。
4、程序缺少主心骨:缺少一個(gè)能夠提綱挈領(lǐng)的主干,程序的主干被淹沒(méi)在大量的代碼邏輯之中。
用表驅(qū)動(dòng)法來(lái)實(shí)現(xiàn):
根據(jù)定義的三個(gè)枚舉:模塊類(lèi)型,消息類(lèi)型,自身模塊狀態(tài),定義一個(gè)函數(shù)跳轉(zhuǎn)表:
復(fù)制代碼 代碼如下:

typedef struct  __EVENT_DRIVE
{
 MODE_TYPE mod;//消息的發(fā)送模塊
 EVENT_TYPE event;//消息類(lèi)型
 STATUS_TYPE status;//自身狀態(tài)
 EVENT_FUN eventfun;//此狀態(tài)下的處理函數(shù)指針
}EVENT_DRIVE;
EVENT_DRIVE eventdriver[] = //這就是一張表的定義,不一定是數(shù)據(jù)庫(kù)中的表。也可以使自己定義的一個(gè)結(jié)構(gòu)體數(shù)組。
{
 {MODE_A, EVENT_a, STATUS_1, fun1}
 {MODE_A, EVENT_a, STATUS_2, fun2}
 {MODE_A, EVENT_a, STATUS_3, fun3}
 {MODE_A, EVENT_b, STATUS_1, fun4}
 {MODE_A, EVENT_b, STATUS_2, fun5}

 {MODE_B, EVENT_a, STATUS_1, fun6}
 {MODE_B, EVENT_a, STATUS_2, fun7}
 {MODE_B, EVENT_a, STATUS_3, fun8}
 {MODE_B, EVENT_b, STATUS_1, fun9}
 {MODE_B, EVENT_b, STATUS_2, fun10}
};
int driversize = sizeof(eventdriver) / sizeof(EVENT_DRIVE)//驅(qū)動(dòng)表的大小
EVENT_FUN GetFunFromDriver(MODE_TYPE mod, EVENT_TYPE event, STATUS_TYPE status)//驅(qū)動(dòng)表查找函數(shù)
{
 int i = 0;
 for (i = 0; i < driversize; i ++)
 {
  if ((eventdriver[i].mod == mod) && (eventdriver[i].event == event) && (eventdriver[i].status == status))
  {
   return eventdriver[i].eventfun;
  }
 }
 return NULL;
}

這種方法的好處:
1、提高了程序的可讀性。一個(gè)消息如何處理,只要看一下驅(qū)動(dòng)表就知道,非常明顯。
2、減少了重復(fù)代碼。這種方法的代碼量肯定比第一種少。為什么?因?yàn)樗岩恍┲貜?fù)的東西:switch分支處理進(jìn)行了抽象,把其中公共的東西——根據(jù)三個(gè)元素查找處理方法抽象成了一個(gè)函數(shù)GetFunFromDriver外加一個(gè)驅(qū)動(dòng)表。
3、可擴(kuò)展性。注意這個(gè)函數(shù)指針,他的定義其實(shí)就是一種契約,類(lèi)似于java中的接口,c++中的純虛函數(shù),只有滿足這個(gè)條件(入?yún)?,返回值),才可以作為一個(gè)事件的處理函數(shù)。這個(gè)有一點(diǎn)插件結(jié)構(gòu)的味道,你可以對(duì)這些插件進(jìn)行方便替換,新增,刪除,從而改變程序的行為。而這種改變,對(duì)事件處理函數(shù)的查找又是隔離的(也可以叫做隔離了變化)。、
4、程序有一個(gè)明顯的主干。
5、降低了復(fù)雜度。通過(guò)把程序邏輯的復(fù)雜度轉(zhuǎn)移到人類(lèi)更容易處理的數(shù)據(jù)中來(lái),從而達(dá)到控制復(fù)雜度的目標(biāo)。
繼承與組合
考慮一個(gè)事件驅(qū)動(dòng)的模塊,這個(gè)模塊管理很多個(gè)用戶,每個(gè)用戶需要處理很多的事件。那么,我們建立的驅(qū)動(dòng)表就不是針對(duì)模塊了,而是針對(duì)用戶,應(yīng)該是用戶在某狀態(tài)下,收到某模塊的某事件的處理。我們?cè)偌僭O(shè)用戶可以分為不同的級(jí)別,每個(gè)級(jí)別對(duì)上面的提到的處理又不盡相同。

用面向?qū)ο蟮乃悸?,我們可以考慮設(shè)計(jì)一個(gè)用戶的基類(lèi),實(shí)現(xiàn)相同事件的處理方法;根據(jù)級(jí)別不同,定義幾個(gè)不同的子類(lèi),繼承公共的處理,再分別實(shí)現(xiàn)不同的處理。這是最常見(jiàn)的一種思路,可以叫它繼承法。
如果用表驅(qū)動(dòng)法怎么實(shí)現(xiàn)?直接設(shè)計(jì)一個(gè)用戶的類(lèi),沒(méi)有子類(lèi),也沒(méi)有具體的事件的處理方法。它有一個(gè)成員,就是一個(gè)驅(qū)動(dòng)表,它收到事件后,全部委托給這個(gè)驅(qū)動(dòng)表去進(jìn)行處理。針對(duì)用戶的級(jí)別不同,可以定義多個(gè)不同的驅(qū)動(dòng)表來(lái)裝配不同的對(duì)象實(shí)例。這個(gè)可以叫他組合法。

繼承和組合在《設(shè)計(jì)模式》也有提到。組合的優(yōu)勢(shì)在于它的可擴(kuò)展性,彈性,強(qiáng)調(diào)封裝性。
至于這種情況下的驅(qū)動(dòng)表,可以繼續(xù)使用結(jié)構(gòu)體,也可以使用對(duì)象。
上面的方法的一點(diǎn)性能優(yōu)化建議:
如果對(duì)性能要求不高,上面的方法足可以應(yīng)付。如果性能要求很高,可以進(jìn)行適當(dāng)?shù)膬?yōu)化。比如,可以建立一個(gè)多維數(shù)組,每一維分別表示模塊,狀態(tài),消息。這樣,就可以根據(jù)這三者的枚舉直接根據(jù)下標(biāo)定位到處理函數(shù),而不是查表。(其實(shí)還是數(shù)據(jù)驅(qū)動(dòng)的思想:數(shù)據(jù)結(jié)構(gòu)是靜態(tài)的算法。)
數(shù)據(jù)驅(qū)動(dòng)編程再更高級(jí),更為抽象一點(diǎn)的,應(yīng)該就是流程腳本或者DSL了。我曾經(jīng)寫(xiě)過(guò)一個(gè)簡(jiǎn)單的寄生在xml上的腳本來(lái)描述流程。這一塊后面抽時(shí)間介紹。

相關(guān)文章

最新評(píng)論