栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++ aop设计模式,动态横切的实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ aop设计模式,动态横切的实现

动态横切概述
  • 动态横切是通过切入点和连接点在一个方面中创建行为的过程,连接点可以在执行时横向地应用于现有对象。动态横切通常用于帮助向对象层次中的各种方法添加日志记录或身份认证。在很多应用场景中,动态横切技术基本上代表了AOP。
代码地址: https://github.com/luckykelfor/aop/blob/master/multi_aspects_aop.h 调用代码

将上文概述,翻译成代码需求为:

class LogAspect : public aop::BaseAspect
{
public:
    LogAspect(double timestamp, const std::string &name) : m_name_(name), m_timestamp_(timestamp) {}
    LogAspect() : LogAspect(0.0, "NULL") {}
    template 
    void Before(Args &&...)
    {
        std::cout << "[AOP][LogAspect-" << m_name_ << "] Log before calling.  Calling time is " << m_timestamp_ << "n";
    }
    template 
    void After(Args &&...)
    {
        std::cout << "[AOP][LogAspect-" << m_name_ << "] Log after calling.n";
    }

private:
    std::string m_name_;
    double m_timestamp_;
};


class VerifyAspect : public aop::BaseAspect
{
public:
    void Before(int a)
    {
        std::cout << "[AOP][VerifyAspect] Verify before start. a is " << a << "n";
    }
};

// normal funtion
void DoSomething(int a)
{
    std::cout << "Do something imoprtant. a is " << a << "n";
}

// test class
class AAA
{
public:
    void TestA(int a) { std::cout << "This is testA. a is " << a << "n"; }
};

int main()
{
    int a = 0;
    using namespace aop;
    // 测试日志和认证同时包含
    Invoke(LogAspect(1000.0, "LogA"), VerifyAspect(), DoSomething, 54321);
    // 测试包含日志
    Invoke(LogAspect(1000.5, "LogB"), DoSomething, 12345);
    // 测试某一个类的成员函数
    AAA aaa;
    Invoke(LogAspect(), VerifyAspect(), &AAA::TestA, &aaa, 19);
    return 0;
}

实现头文件
#include 
#include 

namespace aop
{
class NonCopyable
{
public:
    NonCopyable() = default;
    ~NonCopyable() = default;
    NonCopyable(const NonCopyable &) = delete;
    NonCopyable &operator=(const NonCopyable &) = delete;
};

class BaseAspect
{
public:
    BaseAspect() = default;
    ~BaseAspect() = default;
    template 
    void Before(Args &&... args) {}
    template 
    void After(Args &&... args) {}
};
template 
class Aspects : public NonCopyable
{
public:
    Aspects(FUNC &&func, AP &&... aps) : m_func_(std::forward(func)), m_aps_(std::make_tuple(std::forward(aps)...))
    {
    }
    template 
    typename std::enable_if::type Invoke(Args &&... args)
    {
        m_func_(std::forward(args)...);
    }

    template 
        typename std::enable_if < I::type Invoke(Args &&... args)
    {
        static_assert(std::is_base_of(m_aps_))>::type>::value, "Aspect class must derives from BaseAspect.n");
        std::get(m_aps_).Before(std::forward(args)...);
        Invoke(std::forward(args)...);
        std::get(m_aps_).After(std::forward(args)...);
    }

private:
    FUNC m_func_;
    std::tuple m_aps_;
};

template 
typename std::enable_if::value>::type Invoke(AP &&... aps, FUNC &&func, Args &&... args)
{
    Aspects(std::forward(func), std::forward(aps)...).Invoke(std::forward(args)...);
}

template 
typename std::enable_if::value>::type Invoke(AP &&... aps, FUNC &&func, TP *target, Args &&... args)
{
    auto bind = [&](Args &&... args) -> void {
        (target->*std::forward(func))(std::forward(args)...);
    };
    Invoke(std::forward(aps)..., bind, std::forward(args)...);
}

} // namespace aop
参考文章

https://blog.csdn.net/chmodzora/article/details/62215207

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号