设计模式-代理模式 C++

一、简介

代理模式属于结构型模式。

代理模式中,一个类代表另一个类的功能。

我们需要创建现有对象的对象,用于对外提供功能接口。

为什么要创建现有对象的对象?

为了限制对某些对象进行访问控制。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

二、静态代理

以租房为例,目前有这样一种中介公司,他们会把房东手中的房源装修成公寓,而公司全权负责对公寓的租赁、管理和维护。租户虽然租的是房东的房屋,但是不会跟房东发生直接的交流。这就是生活中的代理模式。假设我们就是要租一间这样的公寓。

1、先实现一个租房接口类IRentHouse,定义了租房这个服务

class IRentHouse
{
public:
    virtual void rentHouse() = 0;
};

2、房东手中的房源RentHouse 需要继承IRentHouse接口

class Landlord : public IRentHouse
{
public:
    virtual void rentHouse()
    {
        cout << "租了一间房" << endl;
    }
};

3、定义一个代理类,也继承接口IRentHouse,实现对房东的租房控制和管理。代理类需要获取目标对象的指针

class IntermediaryProxy : public IRentHouse
{
public:
    IntermediaryProxy(IRentHouse* iRentHouse):
        _rentHouse(iRentHouse) {}

    ~IntermediaryProxy()
    {
        if(nullptr != _rentHouse)
        {
            delete _rentHouse;
            _rentHouse = nullptr;
        }
    }

    virtual void rentHouse()
    {
        //首先找到中介,交中介费用
        PayIntermediaryFee();

        //中介代理房东租房给客户
        if (nullptr != _rentHouse)
        {
            _rentHouse->rentHouse();
        }

        //中介对房屋进行管理和维修
        ManagerAndMaintain();
    }

private:
    void PayIntermediaryFee()
    {
        cout << "交中介费" << endl;
    }

    void ManagerAndMaintain()
    {
        cout << "管理和维护房屋" << endl;
    }

private:
    IRentHouse* _rentHouse;
};

4、通过中介租房

int main()
{
    IRentHouse* landlord = new Landlord();
    IRentHouse* rentHouseProxy = new IntermediaryProxy(landlord);
    //通过中介租房
    rentHouseProxy->rentHouse();
    delete rentHouseProxy;
    delete landlord;

    system("pause");
    return 0;
}

从静态代理的实现可以看到,只要我们能够获取到“房东”的对象指针,我们还是可以直接从房东租房的。如果我们需要避免用户直接从房东租到房间,可以使用强制代理的方式。

三、强制代理

1、接口类增加GetProxy的声明,GetProxy函数是通过“房东”指针获取代理的方法

class IRentHouse
{
public:
    virtual void rentHouse() = 0;
    virtual IRentHouse* GetProxy() = 0;

    virtual ~IRentHouse() {}
};

2、代理类修改:增加接口类中新函数GetProxy的实现

class IntermediaryProxy : public IRentHouse
{
public:
    IntermediaryProxy(IRentHouse* iRentHouse) :
        _rentHouse(iRentHouse) {}

    virtual ~IntermediaryProxy()
    {
        if (nullptr != _rentHouse)
        {
            delete _rentHouse;
            _rentHouse = nullptr;
        }
    }

    virtual void rentHouse()
    {
        PayInterFee();

        //中介代理房东租房给客户
        if (nullptr != _rentHouse)
        {
            _rentHouse->rentHouse();
        }

        //中介对房屋进行管理和维修
        ManagerAndMaintain();
    }

    virtual IRentHouse* GetProxy()
    {
        return this;
    }

private:
    void PayInterFee()
    {
        cout << "交中介费" << endl;
    }
    void ManagerAndMaintain()
    {
        cout << "中介管理和维护房屋" << endl;
    }

private:
    IRentHouse* _rentHouse;
};

3、房东类修改:1)增加获取代理的方式GetProxy;2、修改rentHouse逻辑,使其无法通过房东指针直接租到房间

class Landlord : public IRentHouse
{
public:
    Landlord() : _proxy(nullptr) {}

    virtual ~Landlord()
    {
        if (nullptr != _proxy)
        {
            delete _proxy;
            _proxy = nullptr;
        }
    }

    virtual void rentHouse()
    {
        if (IsProxy())
        {
            cout << "租了一间房" << endl;
        }
        else
        {
            cout << "请找中介" << endl;
        }
    }

    virtual IRentHouse* GetProxy()
    {
        if (nullptr == _proxy)
        {
            _proxy = new IntermediaryProxy(this);
        }

        return _proxy;
    }

private:
    bool IsProxy()
    {
        //不是中介
        if (nullptr == _proxy)
        {
            return false;
        }

        return true;
    }

private:
    IRentHouse* _proxy;
};

4、调用房东租房(失败),通过房东获取到的代理租房(成功)

int main()
{
    //直接找房东
    IRentHouse* landlord = new Landlord();
    landlord->rentHouse(); //会返回"请找中介"

    landlord->GetProxy()->rentHouse(); //可以租房

    system("pause");
    return 0;
}

【参考&致谢】

https://zhuanlan.zhihu.com/p/72644638https://zhuanlan.zhihu.com/p/72644638

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值