在Delphi中應用AOP實現日誌功能

2021-04-14 11:58:54 字數 3701 閱讀 1205

aop現在很火,網上有這許多支援aop的框架,對於delphi來說同樣也有

meaop

。不過覺得這些框架太複雜了。

現在有乙個系統,基本上都快結束了,整體上當然是沒有採用什麼

aop的框架。對於這樣的系統能否用上

aop的一點點好處呢?

aop簡要說明

根據網上對aop的解釋,它具有下面的特徵: 1

、將通用功能從不相關類之中分離出來;

2、能夠使得很多類共享乙個功能,一旦功能發生變化,不必修改很多類,只要修改這個功能就可以了。

aop的核心在於保持橫切關注點的分離。

日誌功能

這是乙個比較典型的mis系統,現在編碼基本結束。不過某個開發人員接到了乙個繁瑣又看上去沒什麼技術含量的任務——實現日誌功能。這個開發者就是本人了。

好!雖然沒什麼難度,但還是設計一下吧,誰讓我是乙個自詡為高水平的程式設計師呢。

乙個設計圖就這麼做出來了。其中設計乙個介面ilog來封裝日誌實現的細節。模組甲乙丙只需要使用介面ilog就可以。滿足了***物件導向的設計原則。太完美了!

泡杯茶,然後開始寫**實現這個簡單而龐大的任務。

開始編碼了!

tlog,ilog實現比較簡單,在此略去不談。稍微修改一下以前模組的**,將ilog介面傳入每乙個模組中。

接下來只需要實現日誌功能的呼叫就可以了。

模組甲:

proceduretmodule1.acaction1execute(sender: tobject);

begin……

flog.logcommand(「模組甲 操作一」);

end;

proceduretmodule1.acaction2execute(sender: tobject);

begin……

flog.logcommand(「模組甲 操作二」);

end;

模組乙:

proceduretmodule2.acaction1execute(sender: tobject);

begin……

flog.logcommand(「模組乙 操作一」);

end;

就這樣,寫了大約二十幾個地方,突然覺得自己太可悲了,作為乙個高科技人才就幹這種體力活嗎?

壞味道的出現

在許許多多的地方都出現了flog.logcommand這樣的函式呼叫,正是這些函式呼叫讓我崩潰,在這麼做下去估計我撐不到週末了。

「cv**」已經讓我覺得羞愧加惱怒,系統中到處出現了這樣的重複**。

無奈之中,我耷拉著腦袋走到乙個同事桌前。

「嘿,救救我吧,我想解脫」

「怎麼回事?」同事善意地問道。

「事情是這樣子的……」

通過了一番討論,我們一致認為這個應該用aop的思想來解決。但怎樣在delphi中來實現aop呢,修改整個程式框架是不可能的,我們只能在現有的基礎上做。

曙光啊,曙光!

解決方式——瞞天過海

通俗點理解aop,就是將一段**統一「插入」某一類地方。但像delphi這樣的語言是很難實現「插入」**的這一功能。不過我們可以通過事件機制來實現同樣的效果。

action的執行**都寫在事件onexecute中,如果能在執行事件之前和之後執行我想要的動作是不是就可以解決了?

proceduretmodule1.acaction1execute(sender: tobject);

begin

// do something

end;

proceduretactionhook.registeraction(action: taction);

begin

// 記錄

action

與原始的

onexecute

事件 factionlist.add(action);

setlength(factionevents, length(factionevents) + 1);

factionevents[high(factionevents)] := action.onexecute;

// 瞞天過海,偷換事件

action.onexecute := hookactionexecute;

end;

proceduretactionhook.hookactionexecute(asender: tobject);

begin

dobeforeactionexecute(taction(asender));

// 觸發原始事件

factionevents[factionlist.indexof(asender)](asender);

doafteractionexecute(taction(asender));

end;

proceduretactionhook.doafteractionexecute(action: taction);

begin

// 所有的

action

執行完畢後呼叫此處

flog.logcommand(action.caption);

end;

相關的uml圖如下:

採用這樣的方式後,很明顯我們不需要將日誌相關**分散到系統的各個地方,只需要在乙個統一的地方將所有

form上的action元件註冊到tactionhook中就可以了。

擴充套件思考

在delphi中可以通過事件的機制實現**注入技術,當然同樣在其他支援事件的語言中也可以實現。相比之下這種方法實現aop比較簡單,並且不需要在系統的整體結構上作什麼調整,完全通過語言層面支援。

例子中針對action的元件來處理日誌功能,將tactionhook擴充套件之後可以將其他的控制項操作也通過這套機制記錄到日誌中。

很多同行們都埋怨自己做的是體力活,沒什麼技術含量。同樣在剛開始的時候,我也認為這個任務是體力活,但是如果我們能勤於思考新的解決方法,體力活絕對能夠變為技術活。只有這樣才能不辜負「高科技」這個美譽啊。

上面介紹的方法肯定不是最好的,這次拿出來和大家分享,一方面是將自己的經驗獻給需要的朋友,另外也特別希望大家能給一點好的建議,一起交流,共同學習。

在Delphi中應用AOP實現日誌功能

aop現在很火,網上有這許多支援aop的框架,對於delphi來說同樣也有 meaop 不過覺得這些框架太複雜了。現在有乙個系統,基本上都快結束了,整體上當然是沒有採用什麼 aop的框架。對於這樣的系統能否用上 aop的一點點好處呢?aop簡要說明 根據網上對aop的解釋,它具有下面的特徵 1 將通...

在Delphi中應用AOP實現日誌功能

aop現在很火,網上有這許多支援aop的框架,對於delphi來說同樣也有 meaop 不過覺得這些框架太複雜了。現在有乙個系統,基本上都快結束了,整體上當然是沒有採用什麼 aop的框架。對於這樣的系統能否用上 aop的一點點好處呢?aop簡要說明 根據網上對aop的解釋,它具有下面的特徵 1 將通...

在Delphi中應用AOP實現日誌功能

aop現在很火,網上有這許多支援aop的框架,對於delphi來說同樣也有 meaop 不過覺得這些框架太複雜了。現在有乙個系統,基本上都快結束了,整體上當然是沒有採用什麼 aop的框架。對於這樣的系統能否用上 aop的一點點好處呢?aop簡要說明 根據網上對aop的解釋,它具有下面的特徵 1 將通...