www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 程序喵大人
[導(dǎo)讀]【多數(shù)人都擁有自己不了解的能力和機會,都有可能做到未曾夢想的事情?!鳡枴た突?——卡耐基 前面的文章中程序喵分享過設(shè)計模式中所有的創(chuàng)建型模式,今天開始結(jié)構(gòu)型模式的分享,結(jié)構(gòu)型模式主要總結(jié)了一些類和對象組合的框架,這些框架通常用于解決某


【多數(shù)人都擁有自己不了解的能力和機會,都有可能做到未曾夢想的事情?!鳡枴た突?/p>


——卡耐基


前面的文章中程序喵分享過設(shè)計模式中所有的創(chuàng)建型模式,今天開始結(jié)構(gòu)型模式的分享,結(jié)構(gòu)型模式主要總結(jié)了一些類和對象組合的框架,這些框架通常用于解決某些特定場景的問題。 今天開始分享結(jié)構(gòu)型模式的第一個模式:代理模式。

代理模式中通常有三個角色,一個是抽象產(chǎn)品角色,一個是具體產(chǎn)品角色,另一個是代理產(chǎn)品角色,這個代理產(chǎn)品角色的作用是什么呢?引入了代理產(chǎn)品角色是為了給原始的具體產(chǎn)品附加功能。注意這里代理模式附加的是跟原始類無關(guān)的功能,附加的如果是跟原始類有關(guān)的功能那是裝飾器模式,后續(xù)程序喵會介紹。

代碼實現(xiàn)如下:

struct Product { virtual ~Product() {} virtual void Use() = 0;};
struct ConcreteProduct : public Product { void Use() override { std::cout << "use product\n"; }};
struct ProductProxy : public Product { private: Product *product_;
public: ProductProxy() { product_ = new ConcreteProduct(); }
~ProductProxy() { delete product_; }
void Use() override { auto begin_use = [] { std::cout << "use product begin\n"; }; auto end_use = [] { std::cout << "use product end\n"; }; begin_use(); product_->Use(); end_use(); }};
int main() { ProductProxy proxy; proxy.Use(); return 0;}

上述代碼即使用了代理模式為某個類附加了一些額外的功能,這里為具體產(chǎn)品類使用前后附加了一些log功能,平時開發(fā)過程中如果我們想要為某個類附加一些額外功能時,可以考慮使用代理模式。

C++中的切面編程(AOP)也可以理解為是一種代理模式:

#include <sys/time.h>
#include <ctime>#include <iostream>
using namespace std;
#define HAS_MEMBER(member) \ template <typename T, typename... Args> \ struct has_member_##member { \ private: \ template <typename U> \ static auto Check(int) -> decltype(std::declval<U>().member(std::declval<Args>()...), std::true_type()); \ template <typename U> \ static std::false_type Check(...); \ \ public: \ enum { value = std::is_same<decltype(Check<T>(0)), std::true_type>::value }; \ };
HAS_MEMBER(Foo)HAS_MEMBER(Before)HAS_MEMBER(After)
template <typename Func, typename... Args>struct Aspect { Aspect(Func&& f) : m_func(std::forward<Func>(f)) {}
template <typename T> typename std::enable_if<has_member_Before<T, Args...>::value && has_member_After<T, Args...>::value>::type Invoke( Args&&... args, T&& aspect) { aspect.Before(std::forward<Args>(args)...); //核心邏輯之前的切面邏輯 m_func(std::forward<Args>(args)...); //核心邏輯 aspect.After(std::forward<Args>(args)...); //核心邏輯之后的切面邏輯 }
template <typename T> typename std::enable_if<has_member_Before<T, Args...>::value && !has_member_After<T, Args...>::value>::type Invoke( Args&&... args, T&& aspect) { aspect.Before(std::forward<Args>(args)...); //核心邏輯之前的切面邏輯 m_func(std::forward<Args>(args)...); //核心邏輯 }
template <typename T> typename std::enable_if<!has_member_Before<T, Args...>::value && has_member_After<T, Args...>::value>::type Invoke( Args&&... args, T&& aspect) { m_func(std::forward<Args>(args)...); //核心邏輯 aspect.After(std::forward<Args>(args)...); //核心邏輯之后的切面邏輯 }
template <typename Head, typename... Tail> void Invoke(Args&&... args, Head&& headAspect, Tail&&... tailAspect) { headAspect.Before(std::forward<Args>(args)...); Invoke(std::forward<Args>(args)..., std::forward<Tail>(tailAspect)...); headAspect.After(std::forward<Args>(args)...); }
private: Func m_func; //被織入的函數(shù)};template <typename T>using identity_t = T;
// AOP的輔助函數(shù),簡化調(diào)用template <typename... AP, typename... Args, typename Func>void Invoke(Func&& f, Args&&... args) { Aspect<Func, Args...> asp(std::forward<Func>(f)); asp.Invoke(std::forward<Args>(args)..., identity_t<AP>()...);}
struct TimeElapsedAspect { void Before(int i) { m_lastTime = GetTime(); }
void After(int i) { cout << "time used: " << GetTime() - m_lastTime << endl; }
private: long long m_lastTime;
long long GetTime() { struct timeval time; gettimeofday(&time, NULL); return static_cast<long long>(time.tv_sec * 1000) + static_cast<long long>(time.tv_usec / 1000); }};
struct LoggingAspect { void Before(int i) { std::cout << "begin" << std::endl; }
void After(int i) { std::cout << "end" << std::endl; }};
void Func(int a) { cout << "Function: " << a << endl; }
int main() { Invoke<LoggingAspect, TimeElapsedAspect>(&Func, 1); //織入方法 cout << "-----------------------" << endl; Invoke<TimeElapsedAspect, LoggingAspect>(&Func, 1);
return 0;}

通過AOP可以為某個函數(shù)前后編織切入一些方法,組成一個新的函數(shù),這里也起到了代理作用,可以理解為一種靜態(tài)代理。

參考資料

https://www.runoob.com/design-pattern/proxy-pattern.html
https://www.cnblogs.com/qicosmos/p/4772389.html


往期推薦





免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉