首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 輕量級 AOP 實踐:利用 Action 事件攔截器統一實作日誌功能

     編輯:Delphi

痛點:散落各處的日誌調用

專案尾聲需補充日誌功能,傳統做法在每個 Action 執行處手寫 FLog.LogCommand('...'),二十餘處重複程式碼讓開發者陷入「複製貼上」泥沼,違反 DRY 原則,維護成本極高。

AOP 核心思想輕量落地

AOP 核心為橫切關注點分離:將通用功能(日誌、效能監控、權限檢查)從業務邏輯中抽離,在「切點」統一織入。Delphi 雖無原生 AOP 框架,但事件機制可模擬「方法攔截」:

  • 所有業務操作均綁定 TAction.OnExecute 事件。
  • 在事件觸發前/後插入通用邏輯,即為「環繞通知」。

解決方案:TActionHook 攔截器

核心程式碼

type
  TActionHook = class
  private
    FActionList: TList;
    FActionEvents: array of TNotifyEvent;
    FLog: ILog;
    procedure HookActionExecute(Sender: TObject);
    procedure DoBeforeActionExecute(Action: TAction);
    procedure DoAfterActionExecute(Action: TAction);
  public
    constructor Create(ALog: ILog);
    procedure RegisterAction(Action: TAction);
    destructor Destroy; override;
  end;

procedure TActionHook.RegisterAction(Action: TAction);
begin
  FActionList.Add(Action);
  SetLength(FActionEvents, Length(FActionEvents) + 1);
  FActionEvents[High(FActionEvents)] := Action.OnExecute; // 保存原始事件
  Action.OnExecute := HookActionExecute; // 偷換事件
end;

procedure TActionHook.HookActionExecute(Sender: TObject);
var idx: Integer;
begin
  DoBeforeActionExecute(TAction(Sender));
  idx := FActionList.IndexOf(Sender);
  if Assigned(FActionEvents[idx]) then
    FActionEvents[idx](Sender); // 執行原始業務邏輯
  DoAfterActionExecute(TAction(Sender));
end;

procedure TActionHook.DoAfterActionExecute(Action: TAction);
begin
  FLog.LogCommand(Action.Caption); // 統一日誌:以 Action.Caption 為操作描述
end;

使用方式

系統啟動時,遍歷所有表單的 TAction 元件,逐一 RegisterAction。業務程式碼零修改,日誌自動生效。

架構優勢

  • 零侵入:業務邏輯完全不知日誌存在。
  • 集中維護:日誌格式、輸出目標、過濾規則只改一處。
  • 擴展性:DoBeforeActionExecute 可加入權限檢查、效能計時;支援擴展至 TButton.OnClick 等其他事件型別。
  • 語言原生:無需外部框架、無反射開銷、編譯期型別安全。

避坑指南

  • 註冊時必須保存原始事件參考,否則業務邏輯丟失。
  • 攔截器生命週期應覆蓋應用程式主生命週期,避免釋放後事件觸發存取已釋放物件。
  • 若 Action 為動態建立,需在建立後立即註冊。

心得

「體力活」往往隱藏著架構改良契機。善用語言特性(事件、介面、泛型)實踐 AOP 核心思想,能以最小成本解決橫切關注點,讓程式碼乾淨、可維護、可演進。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved