代理设计模式

一、概述

        代理设计模式是一种结构型设计模式,它允许在一个对象和其它对象之间添加一个代理对象,以控制对原始对象的访问。代理对象通常在访问原始对象之前或之后执行一些额外的操作,例如记录日志、控制访问权限、缓存结果等。在C++中,代理设计模式可以使用类、函数指针、函数对象等方式来实现。

二、代理设计模式的实现方式

        在C++中,代理设计模式有多种实现方式,包括类代理、函数指针代理、函数对象代理等。

1. 类代理

        类代理是一种常见的代理实现方式,它使用一个代理类来封装原始对象,并实现与原始对象相同的接口。下面是一个类代理的实现代码:

class Subject {
public:
    virtual void request() = 0;
};
class RealSubject : public Subject {
public:
    void request() override {
        std::cout << "RealSubject::request" << std::endl;
    }
};
class Proxy : public Subject {
public:
    Proxy() : m_subject(new RealSubject()) {}
    ~Proxy() { delete m_subject; }
    void request() override {
        // 在访问原始对象之前或之后执行一些额外的操作
        std::cout << "Proxy::request" << std::endl;
        m_subject->request();
    }
private:
    Subject* m_subject;
};

        上述代码中,Subject是一个抽象接口,定义了请求的接口函数request()。RealSubject是一个实现类,实现了请求的接口函数,并在其中输出了一条日志信息。Proxy是一个代理类,它也实现了请求的接口函数,并在其中执行一些额外的操作,例如输出一条日志信息,并调用原始对象的接口函数。

        使用类代理的好处是,可以在代理类中进行更多的控制和管理操作,例如记录日志、控制访问权限、缓存结果等。

2. 函数指针代理   

        函数指针代理是一种使用函数指针来实现代理的方式。下面是一个函数指针代理的实现代码:

using RequestFunc = std::function<void()>;
void RealRequest() {
    std::cout << "RealRequest" << std::endl;
}
void ProxyRequest(RequestFunc func) {
    // 在访问原始函数之前或之后执行一些额外的操作
    std::cout << "ProxyRequest" << std::endl;
    func();
}
int main() {
    RequestFunc func = RealRequest;
    ProxyRequest(func);
    return 0;
}

        上述代码中,RealRequest是一个实际执行请求的函数,它输出了一条日志信息。ProxyRequest是一个代理函数,它使用函数指针来接收RealRequest函数,并在其中执行一些额外的操作,例如输出一条日志信息。在main函数中,使用函数指针将RealRequest函数传递给ProxyRequest函数,实现了代理

3. 函数对象代理

        函数对象代理是一种使用函数对象来实现代理的方式。函数对象是一种重载了函数调用操作符()的对象,它可以像函数一样被调用。下面是一个函数对象代理的实现代码:

class RealRequest {
public:
    void operator()() {
        std::cout << "RealRequest" << std::endl;
    }
};
class ProxyRequest {
public:
    ProxyRequest(RealRequest& realRequest) : m_realRequest(realRequest) {}
    void operator()() {
        // 在访问原始对象之前或之后执行一些额外的操作
        std::cout << "ProxyRequest" << std::endl;
        m_realRequest();
    }
private:
    RealRequest& m_realRequest;
};
int main() {
    RealRequest realRequest;
    ProxyRequest proxyRequest(realRequest);
    proxyRequest();
    return 0;
}

        上述代码中,RealRequest是一个实现了函数调用操作符()的类,它实现了请求的具体操作,并输出了一条日志信息。ProxyRequest是一个代理类,它接收一个RealRequest对象,并在其中执行一些额外的操作,例如输出一条日志信息。在main函数中,创建了一个RealRequest对象和一个ProxyRequest对象,并通过函数调用操作符()来调用代理对象的请求操作。

        使用函数对象代理的好处是,可以将代理对象的请求操作封装在一个对象中,并且可以方便地传递和管理代理对象。

三、代理设计模式的适用场景

代理设计模式在以下场景中特别有用:

    1. 远程代理:将一个对象代理到不同的地址空间中,例如通过网络连接远程对象。

    2. 虚拟代理:通过代理来代替一个真正的对象,以便在需要时才创建或初始化真正的对象。

    3. 安全代理:控制对一个对象的访问权限,例如只允许授权用户访问某些资源。

    4. 缓存代理:为一些开销大的操作提供缓存,以便在需要时重用结果。

    5. 日志记录代理:在访问一个对象时添加日志记录功能,以便跟踪对象的使用情况。

四、总结

    代理设计模式是一种实用的设计模式,它可以在不改变原始对象的情况下控制对其的访问,并在访问前后执行一些额外的操作。在C++中,代理设计模式可以使用类、函数指针、函数对象等方式来实现。代理设计模式适用于远程代理、虚拟代理、安全代理、缓存代理、日志记录代理等场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中的代理设计模式是一种结构型设计模式。它允许一个对象(代理)代替另一个对象(被代理对象)来访问其方法。代理对象可以通过实现与被代理对象相同的接口或继承相同的父类来完成这个任务。 代理对象可以在不改变被代理对象的基本逻辑的情况下,为其添加额外的功能,例如记录日志、缓存数据、权限控制等。代理对象还可以对被代理对象的方法进行验证或重写。 在Java中,代理模式有两种实现方式:静态代理和动态代理。静态代理需要手动编写代理类,而动态代理则是在运行时动态生成代理对象。 静态代理示例代码: ```java public interface Subject { void doSomething(); } public class RealSubject implements Subject { public void doSomething() { System.out.println("RealSubject doSomething"); } } public class ProxySubject implements Subject { private RealSubject realSubject; public ProxySubject() { realSubject = new RealSubject(); } public void doSomething() { System.out.println("Before doSomething"); realSubject.doSomething(); System.out.println("After doSomething"); } } public class Client { public static void main(String[] args) { Subject subject = new ProxySubject(); subject.doSomething(); } } ``` 动态代理示例代码: ```java public interface Subject { void doSomething(); } public class RealSubject implements Subject { public void doSomething() { System.out.println("RealSubject doSomething"); } } public class ProxyHandler implements InvocationHandler { private Object target; public ProxyHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before " + method.getName()); Object result = method.invoke(target, args); System.out.println("After " + method.getName()); return result; } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); ProxyHandler proxyHandler = new ProxyHandler(realSubject); Subject proxySubject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), proxyHandler); proxySubject.doSomething(); } } ``` 以上是两种代理模式的示例代码。静态代理需要手动编写代理类,但是代理对象的生成在编译时就已经完成。动态代理则是在运行时动态生成代理对象,可以避免代码重复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三贝勒文子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值