在c++++中實現(xiàn)攔截過濾器模式的核心是構(gòu)建可擴(kuò)展的請求預(yù)處理鏈。1. 定義統(tǒng)一的過濾器接口,通過抽象類Filter提供process方法供具體過濾器實現(xiàn);2. 創(chuàng)建filterchain類管理過濾器順序執(zhí)行,使用指針避免對象切片;3. 引入requestcontext結(jié)構(gòu)在過濾器間傳遞共享數(shù)據(jù);4. 可選加入終止機(jī)制,通過索引控制是否繼續(xù)執(zhí)行后續(xù)過濾器;整個過程需注重接口抽象、上下文傳遞與流程控制以確保靈活性和擴(kuò)展性。
在c++中實現(xiàn)攔截過濾器模式(Intercepting Filter Pattern),核心目標(biāo)是構(gòu)建一個請求預(yù)處理鏈,將多個“過濾器”串聯(lián)起來,依次對請求進(jìn)行處理。這種結(jié)構(gòu)廣泛應(yīng)用于Web框架、權(quán)限校驗、日志記錄等場景。
要實現(xiàn)這個模式,關(guān)鍵在于設(shè)計好過濾器的抽象接口和執(zhí)行鏈的管理方式,讓整個流程清晰可控,同時具備良好的擴(kuò)展性。
1. 定義過濾器接口
所有具體的過濾器都應(yīng)該遵循統(tǒng)一的接口規(guī)范。通常我們會定義一個基類或抽象類,包含一個處理方法,比如 execute 或 process。
立即學(xué)習(xí)“C++免費學(xué)習(xí)筆記(深入)”;
class Filter { public: virtual void process() = 0; // 處理請求的核心邏輯 virtual ~Filter() = default; };
每個具體的過濾器繼承這個基類,并實現(xiàn)自己的邏輯。例如:
class AuthenticationFilter : public Filter { public: void process() override { // 模擬身份驗證 std::cout << "AuthenticationFilter: 驗證用戶身份n"; } };
這樣做的好處是,后續(xù)可以輕松地添加新的過濾器而不影響已有代碼。
2. 構(gòu)建過濾器鏈
接下來需要一個機(jī)制來組織這些過濾器,按順序調(diào)用它們。我們可以創(chuàng)建一個 FilterChain 類,用來存儲并依次執(zhí)行過濾器。
class FilterChain { private: std::vector<Filter*> filters; public: void addFilter(Filter* filter) { filters.push_back(filter); } void executeFilters() { for (auto filter : filters) { filter->process(); } } };
使用示例:
int main() { FilterChain chain; AuthenticationFilter authFilter; LoggingFilter logFilter; chain.addFilter(&authFilter); chain.addFilter(&logFilter); chain.executeFilters(); return 0; }
這樣就能按照添加順序依次執(zhí)行各個過濾器。
3. 支持請求上下文傳遞
上面的例子只是模擬了過程,實際應(yīng)用中,過濾器之間往往需要共享一些數(shù)據(jù),比如請求參數(shù)、用戶信息等。因此,我們需要引入一個“請求上下文”對象。
struct RequestContext { std::string user; std::string path; bool isAuthenticated = false; };
然后修改 Filter 接口:
class Filter { public: virtual void process(RequestContext& context) = 0; virtual ~Filter() = default; };
具體實現(xiàn)時就可以根據(jù)上下文做判斷和處理:
class AuthenticationFilter : public Filter { public: void process(RequestContext& context) override { if (context.user == "admin") { context.isAuthenticated = true; std::cout << "AuthenticationFilter: 用戶 " << context.user << " 已通過驗證n"; } else { std::cout << "AuthenticationFilter: 驗證失敗n"; } } };
這樣整個鏈條就可以基于同一個上下文工作,形成真正的處理流程。
4. 可選:加入終止機(jī)制
有些情況下,某個過濾器可能會決定是否繼續(xù)執(zhí)行后續(xù)過濾器。比如權(quán)限不足直接返回錯誤,不進(jìn)入業(yè)務(wù)邏輯。
可以在 FilterChain 中加入一個索引控制:
class FilterChain { private: std::vector<Filter*> filters; int current = 0; public: void addFilter(Filter* filter) { filters.push_back(filter); } void proceed(RequestContext& context) { if (current < filters.size()) { filters[current++]->process(context); } } };
然后每個過濾器在調(diào)用 chain.proceed() 前做一些判斷:
class AuthFilter : public Filter { public: void process(RequestContext& context, FilterChain& chain) { if (context.user != "admin") { std::cout << "拒絕訪問n"; return; } chain.proceed(context); // 繼續(xù)執(zhí)行下一個 } };
這樣的結(jié)構(gòu)更靈活,也更接近實際框架中的實現(xiàn)方式。
總的來說,用C++實現(xiàn)攔截過濾器模式并不復(fù)雜,但要注意幾點:
- 使用抽象類統(tǒng)一接口
- 引入上下文對象便于數(shù)據(jù)共享
- 控制執(zhí)行流程,支持條件中斷
- 盡量避免硬編碼,保持可擴(kuò)展性
基本上就這些,理解清楚結(jié)構(gòu)后,自己封裝一套輕量級的過濾器鏈也不是難事。