(原创)c++11改进我们的模式之改进代理模式,实现通用的AOP框架
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
本次要讲的时候如何改进代理模式,具体来说是动态代理模式,动态代理模式一般实现AOP框架,不懂AOP的童鞋看这里。我前面的博文也实现了一个AOP框架(可以参考我前面的博文:(原创) C++ 轻量级AOP框架),但是那个AOP框架存在一个缺陷,就是不支持切面的组合,这一点大大降低了其通用性,本次通过c++11改进,使AOP框架更完善:支持切面组合,不要求切面必须派生于某个基类,不用虚函数调用,性能更好,功能更强大。
上代码:
struct Aspect : boost::noncopyable
{
template<typename Func>
Aspect(const Func& f) : m_func(f)
{ } template<typename T>
void Invoke(T&& value)
{
value.Before();
m_func();
value.After();
} template<typename Head, typename... Tail>
void Invoke(Head&& head, Tail&&... tail)
{
head.Before();
Invoke(std::forward<Tail>(tail)...);
head.After();
} private:
std::function<void()> m_func;
}; template<typename... AP>
void Invoke(const std::function<void ()>& f)
{
Aspect msp(f);
msp.Invoke(AP()...);
}
切面有要求,切面类中必须要有Before/After方法,否则编译不过,允许空实现。
测试代码:
struct AA
{
void Before()
{
cout<<"Before from AA"<<endl;
} void After()
{
cout<<"After from AA"<<endl;
}
}; struct BB
{
void Before()
{
cout<<"Before from BB"<<endl;
} void After()
{
cout<<"After from BB"<<endl;
}
}; struct CC
{
void Before()
{
cout<<"Before from CC"<<endl;
} void After()
{
cout<<"After from CC"<<endl;
}
}; struct TT
{
void g()
{
cout<<"real g function"<<endl;
} void h(int a)
{
cout<<"real h function: "<<a<<endl;
}
}; struct DD
{
void Before()
{ } void After()
{ }
}; void GT()
{
cout<<"real GT function"<<endl;
} void HT(int a)
{
cout<<"real HT function: "<<a<<endl;
} void TestAOP()
{
TT tt;
std::function<void()> ff = std::bind(&TT::g, &tt);
//组合了两个切面AA BB
Invoke<AA,BB>([&ff](){ff();}); //织入成员函数
Invoke<AA,BB>([&tt](){tt.g();}); //织入对象 int aa = ;
Invoke<AA,BB>(>); //织入方法
Invoke<AA,BB>([aa](){HT(aa);});//织入带参的方法 //织入带参数的成员函数和对象
std::function<void(int)> ff1 = std::bind(&TT::h, &tt, std::placeholders::_1);
Invoke<AA,BB,CC,DD>([&ff1,aa](){ff1(aa);}); //组合了四个切面
Invoke<AA,BB>([&tt,aa](){tt.h(aa);});
}
测试结果:

更新:代码在GCC下编译没问题,但在vs2013下编译不过,是微软的bug,如果要在vs2013下编译通过,需要做一点修改:
template<typename T> using identity_t = T; template<typename... AP>
void Invoke(const std::function<void()>& f)
{
Aspect msp(f);
msp.Invoke(identity_t<AP>()...);
}
(原创)c++11改进我们的模式之改进代理模式,实现通用的AOP框架的更多相关文章
- JAVA代理模式与动态代理模式
1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...
- NET设计模式 第二部分 结构性模式(13):代理模式(Proxy Pattern)
代理模式(Proxy Pattern) ——.NET设计模式系列之十四 Terrylee,2006年5月 摘要:在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对 ...
- 《JAVA与模式》之代理模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...
- [19/04/25-星期四] GOF23_结构型模式(适配器模式、代理模式)
一.引言 结构模式:核心作用就是从程序的结构上实现松耦合,从而扩大整体的类结构,用来解决更大的问题. 二.适配器模式(adapter) 生活中假设笔记本是标准的USB接口但是外置键盘是圆形接口,这时候 ...
- 模式的秘密-代理模式(2)-JDK动态代理
代理模式-动态代理 (1) (2) 代码实践动态代理: 第一步:被代理类的接口: package com.JdkProxy; public interface Moveable { void move ...
- 【设计模式】 模式PK:代理模式VS装饰模式
1.概述 对于两个模式,首先要说的是,装饰模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重对代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能 ...
- Java常见23中设计模式之【代理模式】
一.静态代理模式 静态代理,使用继承的方式实现自己新增的服务 这种模式可以实现帮助被代理者完成一些前期的准备工作和后期的善后工作,但是核心的业务逻辑仍然是由被代理者完成. 在某些情况下,一个客户不想或 ...
- 【编程思想】【设计模式】【结构模式Structural】代理模式Proxy
Python版 https://github.com/faif/python-patterns/blob/master/structural/proxy.py #!/usr/bin/env pytho ...
- java设计模式-----11、代理模式
Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问. 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代 ...
随机推荐
- 如何通过Html网页调用本地安卓app?
如何使用html网页和本地app进行传递数据呢?经过研究,发现还是有方法的,总结了一下,大致有一下几种方式 更新一下吧,这篇日志写于2013年11月,离现在已经很久了,依然很多朋友在查阅.目前应该有更 ...
- 使用perf + FlameGraph生成进程火焰图
FlameGraph代码:https://github.com/cobblau/FlameGraph 使用方法 1,perf record --call-graph dwarf -p 12345 2, ...
- Node单线程高并发原理
一.node是如何处理web请求的 浏览器中的js是单线程的,node也是单线程的.这个单线程相当于一个大管家,一切大小事务都要经过他的手才能办成,它总是把IO任务放入到任务池中. 虽然说是单线程,但 ...
- 【Linux】进程优先级、进程nice值和%nice
用top或者ps命令会输出PRI/PR.NI.%ni/%nice这三种指标值,这些到底是什么东西?先给出大概的解释如下: PRI :进程优先权,代表这个进程可被执行的优先级,其值越小,优先级就越高,越 ...
- mysql常用查询语句
一.查询指定schema下表的个数 select count(TABLE_NAME) from information_schema.tables where table_schema="d ...
- Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用.一 ...
- ES6--变量的声明及解构赋值
ES6的目标是使得JavaScript语言能够用来编写大型的复杂的应用程序.成为企业级开发语言:该标准已于2015年6月17日正式公布. 可是真正的普及我觉得还得须要一段时间.然而这并非理由让我们 ...
- Android中Is library配置的作用
在Android开发中如果用eclipse开发的话,在配置的时候会有一个选项,Is library一直没有研究明白,经过上网查找,有人归纳了用法,归纳的很好作为保留.解决了我多个项目共享资源的好方法. ...
- Android颜色值(RGB)所支持的四种常见形式
Android中颜色值是通过红(Red).绿(Green).蓝(Blue)三原色,以及一个透明度(Alpha)值来表示的,颜色值总是以井号(#)开头,接下来就是Alpha-Red-Green-Blue ...
- 转: 基于elk 实现nginx日志收集与数据分析
原文链接:https://www.cnblogs.com/wenchengxiaopenyou/p/9034213.html 一.背景 前端web服务器为nginx,采用filebeat + logs ...