小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

在Delphi中應(yīng)用AOP實(shí)現(xiàn)日志功能

 獨(dú)孤求財(cái) 2012-03-12

在Delphi中應(yīng)用AOP實(shí)現(xiàn)日志功能

ZDNet軟件頻道 時(shí)間:2007-10-31 作者:陳亮亮 | blog 我要評(píng)論()
本文關(guān)鍵詞:delphi AOP 日志
AOP現(xiàn)在很火,網(wǎng)上有這許多支持AOP的框架,對(duì)于Delphi來(lái)說(shuō)同樣也有MeAOP。不過(guò)覺(jué)得這些框架太復(fù)雜了。
AOP現(xiàn)在很火,網(wǎng)上有這許多支持AOP的框架,對(duì)于delphi來(lái)說(shuō)同樣也有MeAOP。不過(guò)覺(jué)得這些框架太復(fù)雜了。

  現(xiàn)在有一個(gè)系統(tǒng),基本上都快結(jié)束了,整體上當(dāng)然是沒(méi)有采用什么AOP的框架。對(duì)于這樣的系統(tǒng)能否用上AOP的一點(diǎn)點(diǎn)好處呢?

  項(xiàng)目組提出在現(xiàn)有的系統(tǒng)上加入日志記錄的需求。大家一起來(lái)看看我是怎么來(lái)實(shí)現(xiàn)這個(gè)功能的吧。

  AOP簡(jiǎn)要說(shuō)明

  根據(jù)網(wǎng)上對(duì)AOP的解釋?zhuān)哂邢旅娴奶卣鳎?BR>
  1、將通用功能從不相關(guān)類(lèi)之中分離出來(lái);
  
  2、能夠使得很多類(lèi)共享一個(gè)功能,一旦功能發(fā)生變化,不必修改很多類(lèi),只要修改這個(gè)功能就可以了。
  
  AOP的核心在于保持橫切關(guān)注點(diǎn)的分離。

  日志功能

  這是一個(gè)比較典型的MIS系統(tǒng),現(xiàn)在編碼基本結(jié)束。不過(guò)某個(gè)開(kāi)發(fā)人員接到了一個(gè)繁瑣又看上去沒(méi)什么技術(shù)含量的任務(wù)——實(shí)現(xiàn)日志功能。這個(gè)開(kāi)發(fā)者就是本人了。

  雖然沒(méi)什么難度,但還是設(shè)計(jì)一下吧,誰(shuí)讓我是一個(gè)自詡為高水平的程序員呢。



  一個(gè)設(shè)計(jì)圖就這么做出來(lái)了。其中設(shè)計(jì)一個(gè)接口ILog來(lái)封裝日志實(shí)現(xiàn)的細(xì)節(jié)。模塊甲乙丙只需要使用接口ILog就可以。滿(mǎn)足了XXX面向?qū)ο蟮脑O(shè)計(jì)原則。太完美了!

  泡杯茶,然后開(kāi)始寫(xiě)代碼實(shí)現(xiàn)這個(gè)簡(jiǎn)單而龐大的任務(wù)。
 
  開(kāi)始編碼了!

  TLog,ILog實(shí)現(xiàn)比較簡(jiǎn)單,在此略去不談。稍微修改一下以前模塊的代碼,將ILog接口傳入每一個(gè)模塊中。

  接下來(lái)只需要實(shí)現(xiàn)日志功能的調(diào)用就可以了。

  模塊甲:

procedure TModule1.acAction1Execute(Sender: TObject);
begin
……
Flog.LogCommand(“模塊甲 操作一”);
end;

procedure TModule1.acAction2Execute(Sender: TObject);
begin
……
Flog.LogCommand(“模塊甲 操作二”);
end;

  模塊乙:

procedure TModule2.acAction1Execute(Sender: TObject);
begin
……
Flog.LogCommand(“模塊乙 操作一”);
end;

  就這樣,寫(xiě)了大約二十幾個(gè)地方,突然覺(jué)得自己太可悲了,作為一個(gè)高科技人才就干這種體力活嗎?
 
  壞味道的出現(xiàn)
 
  在許許多多的地方都出現(xiàn)了Flog.LogCommand這樣的函數(shù)調(diào)用,正是這些函數(shù)調(diào)用讓我崩潰,在這么做下去估計(jì)我撐不到周末了。

  “CV大法”已經(jīng)讓我覺(jué)得羞愧加惱怒,系統(tǒng)中到處出現(xiàn)了這樣的重復(fù)代碼。

  無(wú)奈之中,我耷拉著腦袋走到一個(gè)同事桌前。

  “嘿,救救我吧,我想解脫”

  “怎么回事?”同事善意地問(wèn)道。

  “事情是這樣子的……”

  通過(guò)了一番討論,我們一致認(rèn)為這個(gè)應(yīng)該用AOP的思想來(lái)解決。但怎樣在delphi中來(lái)實(shí)現(xiàn)AOP呢,修改整個(gè)程序框架是不可能的,我們只能在現(xiàn)有的基礎(chǔ)上做。

  正當(dāng)我們要放棄的時(shí)候,突然想到了一個(gè)突破點(diǎn):日志中記錄的功能在程序?qū)崿F(xiàn)的時(shí)候全部使用Action組件來(lái)做的,是否可以考慮在Action上面做文章呢?

  曙光啊,曙光!

  解決方式——瞞天過(guò)海

  通俗點(diǎn)理解AOP,就是將一段代碼統(tǒng)一“插入”某一類(lèi)地方。但像delphi這樣的語(yǔ)言是很難實(shí)現(xiàn)“插入”代碼的這一功能。不過(guò)我們可以通過(guò)事件機(jī)制來(lái)實(shí)現(xiàn)同樣的效果。

  Action的執(zhí)行代碼都寫(xiě)在事件OnExecute中,如果能在執(zhí)行事件之前和之后執(zhí)行我想要的動(dòng)作是不是就可以解決了?

procedure TModule1.acAction1Execute(Sender: TObject);
begin
// do something
end;

procedure TActionHook.RegisterAction(Action: TAction);
begin
// 記錄Action與原始的OnExecute事件
FActionList.Add(Action);
SetLength(FActionEvents, Length(FActionEvents) + 1);
FActionEvents[High(FActionEvents)] := Action.OnExecute;
// 瞞天過(guò)海,偷換事件
Action.OnExecute := HookActionExecute;
end;

procedure TActionHook.HookActionExecute(ASender: TObject);
begin
DoBeforeActionExecute(TAction(ASender));
// 觸發(fā)原始事件
FActionEvents[FActionList.IndexOf(ASender)](ASender);
DoAfterActionExecute(TAction(ASender));
end;

procedure TActionHook.DoAfterActionExecute(Action: TAction);
begin
// 所有的Action執(zhí)行完畢后調(diào)用此處
FLog.LogCommand(Action.Caption);
end;

  相關(guān)的UML圖如下:


  采用這樣的方式后,很明顯我們不需要將日志相關(guān)代碼分散到系統(tǒng)的各個(gè)地方,只需要在一個(gè)統(tǒng)一的地方將所有Form上的Action組件注冊(cè)到TActionHook中就可以了。

  擴(kuò)展思考

  在delphi中可以通過(guò)事件的機(jī)制實(shí)現(xiàn)代碼注入技術(shù),當(dāng)然同樣在其他支持事件的語(yǔ)言中也可以實(shí)現(xiàn)。相比之下這種方法實(shí)現(xiàn)AOP比較簡(jiǎn)單,并且不需要在系統(tǒng)的整體結(jié)構(gòu)上作什么調(diào)整,完全通過(guò)語(yǔ)言層面支持。

  例子中針對(duì)Action的組件來(lái)處理日志功能,將TActionHook擴(kuò)展之后可以將其他的控件操作也通過(guò)這套機(jī)制記錄到日志中。

  很多同行們都埋怨自己做的是體力活,沒(méi)什么技術(shù)含量。同樣在剛開(kāi)始的時(shí)候,我也認(rèn)為這個(gè)任務(wù)是體力活,但是如果我們能勤于思考新的解決方法,體力活絕對(duì)能夠變?yōu)榧夹g(shù)活。只有這樣才能不辜負(fù)“高科技”這個(gè)美譽(yù)啊。

  上面介紹的方法肯定不是最好的,這次拿出來(lái)和大家分享,一方面是將自己的經(jīng)驗(yàn)獻(xiàn)給需要的朋友,另外也特別希望大家能給一點(diǎn)好的建議,一起交流,共同學(xué)習(xí)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多