最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入數(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語言。
之前介紹過數(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ì)的描述可以看一下《代碼大全》,有一章專門進(jìn)行描述(大概是第八章)。
簡(jiǎn)單的表驅(qū)動(dòng):
淺談:什么是數(shù)據(jù)驅(qū)動(dòng)編程的詳解》中有一個(gè)代碼示例。它其實(shí)也可以看做是一種表驅(qū)動(dòng)手法,只不過這個(gè)表相對(duì)比較簡(jiǎn)單,它在收到消息后,根據(jù)消息類型確定使用調(diào)用什么函數(shù)進(jìn)行處理。
復(fù)雜一點(diǎn)的表驅(qū)動(dòng):
考慮一個(gè)消息(事件)驅(qū)動(dòng)的系統(tǒng),系統(tǒng)的某一模塊需要和其他的幾個(gè)模塊進(jìn)行通信。它收到消息后,需要根據(jù)消息的發(fā)送方,消息的類型,自身的狀態(tài),進(jìn)行不同的處理。比較常見的一個(gè)做法是用三個(gè)級(jí)聯(lián)的switch分支實(shí)現(xiàn)通過硬編碼來實(shí)現(xiàn):
復(fù)制代碼 代碼如下:

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

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

typedef struct  __EVENT_DRIVE
{
 MODE_TYPE mod;//消息的發(fā)送模塊
 EVENT_TYPE event;//消息類型
 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í)就是一種契約,類似于java中的接口,c++中的純虛函數(shù),只有滿足這個(gè)條件(入?yún)?,返回值),才可以作為一個(gè)事件的處理函數(shù)。這個(gè)有一點(diǎn)插件結(jié)構(gòu)的味道,你可以對(duì)這些插件進(jìn)行方便替換,新增,刪除,從而改變程序的行為。而這種改變,對(duì)事件處理函數(shù)的查找又是隔離的(也可以叫做隔離了變化)。、
4、程序有一個(gè)明顯的主干。
5、降低了復(fù)雜度。通過把程序邏輯的復(fù)雜度轉(zhuǎn)移到人類更容易處理的數(shù)據(jù)中來,從而達(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è)用戶的基類,實(shí)現(xiàn)相同事件的處理方法;根據(jù)級(jí)別不同,定義幾個(gè)不同的子類,繼承公共的處理,再分別實(shí)現(xiàn)不同的處理。這是最常見的一種思路,可以叫它繼承法。
如果用表驅(qū)動(dòng)法怎么實(shí)現(xiàn)?直接設(shè)計(jì)一個(gè)用戶的類,沒有子類,也沒有具體的事件的處理方法。它有一個(gè)成員,就是一個(gè)驅(qū)動(dòng)表,它收到事件后,全部委托給這個(gè)驅(qū)動(dòng)表去進(jìn)行處理。針對(duì)用戶的級(jí)別不同,可以定義多個(gè)不同的驅(qū)動(dòng)表來裝配不同的對(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)寫過一個(gè)簡(jiǎn)單的寄生在xml上的腳本來描述流程。這一塊后面抽時(shí)間介紹。

相關(guān)文章

最新評(píng)論

化州市| 准格尔旗| 屏山县| 桃园县| 景宁| 柯坪县| 潍坊市| 长顺县| 顺平县| 阳泉市| 綦江县| 弥勒县| 亳州市| 黎川县| 白城市| 黑河市| 铜山县| 灌南县| 青浦区| 大余县| 宝应县| 惠安县| 阜新市| 嘉荫县| 屯留县| 交口县| 宜兰县| 德令哈市| 盐边县| 淮北市| 昌乐县| 新平| 玛纳斯县| 元谋县| 陆川县| 沂南县| 西峡县| 任丘市| 青川县| 牡丹江市| 新龙县|