代理模式和适配器模式
1.适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 ---百度百科
简单来说就是起到应该翻译器的作用,将真实的接口包装成用户所需要的接口。
就拿看日剧来说,日本原产的语言是日语的,但是当用户是中国人的时候,大部分中国人不懂日语,而为了看日剧去学习日语这个目标在短时间不可能的,所以需要一个翻译组给日剧加上字幕或者中文配音。而在这个例子中,日剧日语就是真实的接口,而中国人就是用户,其中字幕组就是适配器。
优点:
- 用户只需要用直接想用的接口,不需要知道原来的接口是什么
- 真实的接口不需要修改,
缺点:
- 当使用适配器的时候已经表示,用户和真实接口已经很难修改了,但是又存在需求需要两者进行交流,这就表明在设计的初始阶段设计的不当,导致后续的拓展问题
- 该种方法常用在开发后期,因为两端都已经是很难进行修改的,因此常用来做修补匠的功能,而真正的解决方法是在开发的初始阶段就对相关功能的拓展性做好设计
// AdapterModle.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
#define interface struct
interface IWatchTv
{
virtual void wantWatchJapanTV() = 0;
};
class CJapanTV
{
public:
void show()
{
cout << "Show Japan TV." << endl;
}
};
class CToChinese:public IWatchTv
{
private:
CJapanTV m_japanTV;
public:
void wantWatchJapanTV()
{
m_japanTV.show();
cout << "-----subtitle-----!" << endl;
cout << endl;
}
};
int main()
{
IWatchTv *watch = new CToChinese();
watch->wantWatchJapanTV();
return 0;
}
2.代理模式
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 --百度百科
简单来说就是用户需要一个功能的时候,不能直接使用这个类,而需要第三方类进行调用。
- 远程代理。就像是打电话,你不能与给某个人远程进行联系,你需要在三大运营商开卡,然后才能打电话,而三大运营商就类似于代理,你不能直接和对方通讯,你需要使用代理来进行转接。
- 权限限制。这种情况也可能是权限限制,比如普通人可以直接给国务院打通电话吗?一般是不能,需要客服或者专门接电话的人来对你进行筛选,然后你才能打通想要打的电话,这就是权限限制。
- 虚拟代理。就相当于,你打电话的时候,别人正在做其他的事情,你常常听到的就是什么留言信箱啥的,然后对处理完了,会打电话回来。而更直观的例子就像你进入网站的时候,经常是文字先显示,再等图片回来了,慢慢显示图片。
其中ICallPhone就是抽象对象,或者说是业务方法。而CCallPhone就是真实的方法类,另外有就是代理。
而且从uml上看和适配器模式很相似,而如果在代码模式中加一个外部类就可以转变为适配器模式,比如在上图中加入一个国外电话,那么代理也可以作为一个适配器去使用,就是对电话号码进行加工和转译。
优点:
- 保证真实类和用户的分离,即安全也简单
- 真实类的职责清晰,不需要进行其他的方法,只需要去实现一些基本功能函数,具体的结合步骤可以在代理中进行实现。(就相当于各大代理商的各种套餐,真实的类可能就是怎么通讯)
- 拓展性高。
和适配器进行对比:
- 适配器是用来打补丁的,而代理模式是一种很好的架构模式
- 都将用户和真实的类进行了分离,保证了安全性
- 拓展性都不差,代理模式是优质的功能拓展,而适配器只是补丁上面打补丁,不是办法的办法。
// ProxyModle.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
#define interface struct
interface ICallPhone
{
virtual void callPhone() = 0;
};
class CCallPhone:public ICallPhone
{
public:
void callPhone() { cout << "Phone Now!" << endl; }
};
class CCallPhoneProxy :public ICallPhone
{
private:
CCallPhone m_callPhone;
public:
void callPhone() { m_callPhone.callPhone(); }
};
int main()
{
CCallPhoneProxy *proxy = new CCallPhoneProxy();
proxy->callPhone();
}
其中ICallPhone就是抽象对象,或者说是业务方法。而CCallPhone就是真实的方法类,另外有就是代理。
而且从uml上看和适配器模式很相似,而如果在代码模式中加一个外部类就可以转变为适配器模式,比如在上图中加入一个国外电话,那么代理也可以作为一个适配器去使用,就是对电话号码进行加工和转译。
优点:
- 保证真实类和用户的分离,即安全也简单
- 真实类的职责清晰,不需要进行其他的方法,只需要去实现一些基本功能函数,具体的结合步骤可以在代理中进行实现。(就相当于各大代理商的各种套餐,真实的类可能就是怎么通讯)
- 拓展性高。
和适配器进行对比:
- 适配器是用来打补丁的,而代理模式是一种很好的架构模式
- 都将用户和真实的类进行了分离,保证了安全性
- 拓展性都不差,代理模式是优质的功能拓展,而适配器只是补丁上面打补丁,不是办法的办法。
<代码>