设计模式学习(四) 代理模式

本文深入探讨了代理模式的四种应用场景:远程代理、虚代理、保护代理和智能引用,通过QtCreator实现了一个结合虚代理和保护代理的例子,展示如何在需要时加载对象,以及根据条件限制对象访问。


这是个人学习编程模式的系列学习笔记第四篇。
采用Qt Creator进行编写,但尽量采用C++基础语法。
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。有四种常用的情况:(1)远程代理( Remote Proxy ),(2)虚代理(Virtual Proxy),(3)保护代理(Protection Proxy),(4)智能引用(Smart Reference)。
个人理解,由于某些原因,不直接访问具体的对象,需要通过一个代理类来访问对象。比如:
(1)具体要访问的对象在网络上,通过代理类进行访问可以进行网络层面的转换,实现对远程对象的访问,这是远程代理的应用;
(2)具体对象较为复杂,初始化比较慢,占用资源较多。采用代理类来在需要的时候才进行具体对象的实际加载(比如文档中的图片对象的加载比较慢,为保障文档打开的速度,通常在开始只加载图像的代理对象),这是虚代理的应用;
(3)具体对象需要某种保护或权限控制,不允许直接访问具体对象,通过代理对象对访问进行一定的权限控制或安全检查,这是保护代理的应用;
(4)智能引用可理解为更为灵活的指针,可以根据实际需求进行灵活的引用或创建控制(比如在实际第一次引用时加载具体对象,多次引用是计数,没有引用时销毁,或者引用的时候检测使用有别人在用等)。
在实现方式上,代理模式和装饰模式比较类似,先定义接口类,然后具体对象类和代理类都继承这个接口,具有一致的行为模式(代理必然需要与他代理的人具有类似的行为模式)。代理类需要知道具体的代理对象,并有具体的标识能标识其所代理的对象(比如用文件名标识具体的文件对象)。用户调用代理类时,代理类将具体的动作转发给具体的对象进行实际的操作(当然在这之前代理类会根据自己的角色完成对应的工作)。
以下主要用一个例子来演示两种代理模式:虚代理和保护代理。为方便,这两种模式在一个例子中实验,也就是说这个代理同时体现了虚代理和保护代理的工作。

场景描述

假设有一个公司要发布一款新型车,但是新车研发和制作时间长,因此这个公司决定先不研发新车,只有用户提出需要车辆实际上路测试的时候才研发制造新车。(虚代理)
甚至为了尽可能的降低这种制造新车的可能,如果发布会在中国召开的话,就算有上路测试的需求,也只提供测试视频来代替(保护代理)。

设计思路

定义一个Vehicle类作为接口类,再定义一个Car类作为新型号汽车类,一个PPT类作为发布会的演示产品。
定义一个Presentation类作为客户端类,完成演示交互。

UML图

在这里插入图片描述

代码

#include <algorithm>
#include <iostream>

using namespace std;

class Vehicle
{
protected:
    string m_Model;

public:
    Vehicle(string model):m_Model(model) {}
    virtual ~Vehicle(){}

    virtual void run(){}
};

class Car : public Vehicle
{
public:
    Car(string model):Vehicle(model) {}

    void run() { cout<<"This is the new style car on the road! -----"<<m_Model<<"\n"; }
};

class PPT : public Vehicle
{
private:
    string m_Local;
    Car* m_Car = 0;

public:
    PPT(string model, string locale):Vehicle(model),m_Local(locale) {}
    ~PPT(){delete m_Car;}

    void run()
    {
        if(!m_Car)
        {
           if(m_Local == "CHINA")
           {
               cout<<"This is the new style car on the movie!----"<<m_Model<<"\n";
           }
           else
           {
               m_Car = new Car(m_Model);
               m_Car->run();
           }
           return;
        }
        m_Car->run();
        return;
    }
};

class Presentation
{
private:
    Vehicle* m_News = 0;

public:
    Presentation(Vehicle* news):m_News(news) {}
    ~Presentation() {delete m_News;}

    void show(){m_News->run();}

};

int main()
{
    string model = "";
    string local = "";
    cout<<"Please name the new car: ";
    getline(cin, model);
    cout<<"Please input the nation: ";
    getline(cin, local);
    transform(local.begin(), local.end(), local.begin(), ::toupper);
    PPT* ppt = new PPT(model, local);
    Presentation* presentation = new Presentation(ppt);
    presentation->show();
    delete presentation;

    return 0;
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值