代理模式
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问
Subject定义RealSubject和Proxy的共用接口,这样就可以在任何使用RealSubject的地方使用Proxy。
isubject.h
#pragma once
class ISuject
{
public:
virtual ~ISuject() {}
virtual void Request() = 0;
};
RealSubject类,定义Proxy所代表的真实实体
#pragma once
#include "isubject.h"
#include <iostream>
class RealSubject : public ISuject
{
public:
void Request() override
{
std::cout << "真实的请求..." << std::endl;
}
};
Proxy类,保存一个实体的指针或者引用,让代理可以访问实体,并提供一个与Subject的接口相同的接口。这样代理就可以用来替代实体。
proxy.h
#pragma once
#include "isubject.h"
#include "realSubject.h"
class Proxy : public ISuject
{
public:
void Request() override
{
if (m_pRealSubject == nullptr)
{
m_pRealSubject = new RealSubject();
}
m_pRealSubject->Request();
}
~Proxy()
{
if (m_pRealSubject != nullptr)
{
delete m_pRealSubject;
m_pRealSubject = nullptr;
}
}
private:
RealSubject *m_pRealSubject;
};
客户端main.cpp:
#include "proxy.h"
int main()
{
Proxy *proxy = new Proxy();
proxy->Request();
delete proxy;
getchar();
return 0;
}
运行结果:
真实的请求...
适配器模式
UML图表示
代码举例:
target.h
#pragma once
#include <iostream>
class Target
{
public:
virtual ~Target() {}
virtual void Request()
{
std::cout << "普通请求..." << std::endl;
};
};
目标对象Target需要的是一个普通请求的函数接口Request
而需要适配的Adaptee,只有一个特殊请求的函数接口SpecificRequest。怎么样做个转接头,让Adaptee的SpecificRequest可以被目标对象Target当成普通请求来使用?
需要适配的对象adaptee.h
#pragma once
#include <iostream>
class Adaptee
{
public:
void SpecificRequest()
{
std::cout << "特殊请求..." << std::endl;
}
};
适配器adapter.h
#pragma once
#include "target.h"
#include "adaptee.h"
class Adapter : public Target
{
public:
Adapter() : m_adaptee(new Adaptee())
{
}
~Adapter()
{
delete m_adaptee;
m_adaptee = nullptr;
}
void Request() override
{
m_adaptee->SpecificRequest();
}
private:
Adaptee *m_adaptee;
};
客户端main.cpp:
#include "adapter.h"
int main()
{
Target *target = new Adapter();
target->Request();
getchar();
return 0;
}
运行结果:
特殊请求...
我们想这样一个问题,如果适配器模式中的被适配的类Adaptee中SpecificRequest()变成了和Target中一样的Request(),那么适配器模式是不是就和代理模式相同了呢?是的。
这时候,适配器模式中的Target就成了代理模式中的Subject,适配器模式中的Adapter就成了代理模式中的Proxy,适配器模式中的被代理对象Adaptee就成了代理模式中的被代理者RealSubject了。
这就是这两个模式的相似之处。
相同点:
与代理模式的相似之处是,适配器模式也是一个单一组件的包装器。
不同点:
代理模式提供的对外调用接口(public 成员函数),和RealSubject中的是相同的;
而适配器模式提供的对外调用接口(public 成员函数),与目标类Target提供的对外接口相同, 和被适配类Adaptee中的外部接口不同。
归纳为:适配器类的接口可以与原始类的不同,但与目标类的相同。
。而代理模式中的代理类提供与被代理者完全相同的接口。
这是二者的作用不同有关:适配器模式是将一个类的接口转换为一个兼容的但不相同的接口。适配器模式就好像转接头一样,将两个不同的类连接在一起,让他们可以做到其中的一个可以被另外一个调用,尽管他们的接口完全不同。
举个生活中常见的例子:手机需要的是5V的电压,才能进行充电,但是家用电是220V,这时候的手机充电器就充当了一个适配器的角色,它将220V的电压转换成手机可以接受的5V电压。
而代理模式的作用却不同,代理模式是需要和被代理者完全一样的接口,这样代理者在被使用的时候,就可以像使用被代理者一样,让调用者感觉不到这两者的差别。
参考:
适配器模式C++实现
适配器模式C++实现