设计模式之代理大法

本文介绍了代理模式在编程中的作用,如隐藏对象地址、优化创建和增加附加操作,并列举了四种常见场景:远程代理、虚代理、保护代理和智能指针。通过智能指针的例子详细说明了如何实现对象的自动资源管理,防止内存泄漏。同时,文章用幽默的方式强调了设计模式在实际生活中的应用。
摘要由CSDN通过智能技术生成

代理模式,首先我们字面意思直观的理解,所谓代理就是受委托代表当事人进行某种活动。在编程开发中我们也是践行了代理的直观理解。对一个对象的访问,由于代理所以引入了一层间接性,给了我们很大的可操作空间,利用这个特性我们可以进行如下:

1、隐藏一个对象在不同的地址空间事实。

2、可以进行优化,根据要求才创建对象。

3、对一个对象访问之前增加一些附加操作。

代理模式常见的几种场景:

1、远程代理,为一个对象在不同地址空间提供局部代表。

2、虚代理,根据需要创建开销很大的对象。

3、保护代理,控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。

4、智能指针,取代原始指针,访问对象是增加一些附件操作。

这几种常见的场景最熟悉的莫过于智能指针,我们将原始指针封装在一个对象中,重载 *与→操作符,这样我们可以像使用原始指针一样方便,增加对象的引用计数,当引用计数为0时,我们在析构函数中对指针指向的资源进行释放,避免我们因人为的疏忽而遗漏对资源的释放。

其实生活工作中处处充满代理模式,不信你看炊事班的王大锤已经挂了:


#pragma once

#include <iostream>
#include <string>
#include <cstdint>

class Work {
public:
	Work() : WorkValue(0) {}
	Work(uint32_t v) : WorkValue(v) {}
	~Work() {}
	Work(const Work &oh)
	{
		if (this == &oh) {
			return;
		}
		this->WorkValue = oh.GetWorkValue();
	}

	Work& operator=(const Work& oh)
	{
		if (this == &oh) {
			return *this;
		}
		this->WorkValue = oh.GetWorkValue();
		return *this;
	}
	void DoWork()
	{
		WorkValue--;
	}

	uint32_t GetWorkValue() const
	{
		return WorkValue;
	}
private:
	uint32_t WorkValue;
};

class Staff {
public:
	Staff() {}
	virtual ~Staff() {}

	virtual void RcvTask(Work& work) = 0;
	virtual void DoTask() = 0;
	virtual bool TaskState() = 0;
	virtual void TaskResult() = 0;

};

class SecondFool : public Staff {
public:
	SecondFool() {}
	SecondFool(const std::string name) : name(name) {}
    virtual ~SecondFool()
	{
		std::cout << name << ": 已经挂了" << std::endl;
	}

public:
	virtual void RcvTask(Work& work)
	{
		workVal = work;
		std::cout << name << ": 收到任务,马上开始" << std::endl;
	}

	virtual void DoTask()
	{
		while (workVal.GetWorkValue()) {
			std::cout<< name << ": 吭哧 吭哧 ......加班中..." << std::endl;
			workVal.DoWork();
		}
	}
	virtual void TaskResult()
	{
		if (workVal.GetWorkValue() == 0) {
			std::cout<< name << ": 干完了,干完了" << std::endl;
		} else {
			std::cout<< name << ": 再加加班,马上完了" << std::endl;
		}
	}
	virtual bool TaskState()
	{
		if (workVal.GetWorkValue() == 0) {
			return true;
		} else {
			return false;
		}
	}
private:
	std::string name;
	Work workVal;
};

class HumanEssence : public Staff {
public:
	HumanEssence(const std::string name, Staff *staff) : name(name), staff(staff){}
	HumanEssence() {}
	virtual ~HumanEssence()
	{
		std::cout << name << ": 深藏功与名" << std::endl;
	}
	virtual void RcvTask(Work& work)
	{
		uint32_t val = work.GetWorkValue();
		workVal = Work(val / 10);
		std::cout<< name << ": 收到任务,马上开始" << std::endl;
		staff->RcvTask(Work(val / 10 * 9));
	}

	virtual void DoTask()
	{
		while (workVal.GetWorkValue()) {
			std::cout << name << ": 划划水 ...快下班了..." << std::endl;
			workVal.DoWork();
		}
		staff->DoTask();
	}

	virtual bool TaskState()
	{
		return staff->TaskState() ? true : false;
	}

	virtual void TaskResult()
	{
		if (staff->TaskState()) {
			std::cout << name << ": 干完了,干完了" << std::endl;
		}
		else {
			std::cout << name << ": 再加加班,马上完了" << std::endl;
		}
	}

private:
	Staff *staff;
	std::string name;
	Work workVal;
};

class Task {
public:
	Task() {}
	Task(Staff *staff, uint32_t val) : staff(staff), work(Work(10)){}
	~Task()
	{
		std::cout << "任务圆满完成" << std::endl;
	}

	void IssueTask()
	{
		std::cout << "发布任务了,大家加油干" << std::endl;
		staff->RcvTask(work);
	}
	void BeginTask()
	{
		staff->DoTask();
	}

	void TaskResult()
	{
		staff->TaskResult();
	}

private:
	Work work;
	Staff *staff;
};


#include "proxy.h"

using namespace std;

int main()
{
	SecondFool *WangDaChui = new SecondFool("王大锤");
	HumanEssence *LiDaZui = new HumanEssence("李大嘴", WangDaChui);
	Task *task = new Task(LiDaZui, 10);
	task->IssueTask();
	task->BeginTask();
	task->TaskResult();
	delete task;
	delete WangDaChui;
	delete LiDaZui;
	return 0;
}

设计模式好啊, 真地好!
设计模式棒, 真地棒!
我是李大嘴, 无敌的代理,
你是王大锤, 像个二傻子,
设计模式好YE, 真是好!
设计模式好YE, 太棒了!
设计模式够劲, 顶呱呱吖!
我是代理者, 代理者。
他是二傻子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值