标签:
GOF:为其他对象提供一种代理以控制对这个对象的访问。
类图:
适用性:
代理模式还有一种称为copy-on-write的优化方式,如果copy一个对象开销很大,那么只有在改变对象时才copy,如果没有改变对象则用代理来调用原来的对象。
(1)一个简单的代理模式例子:小明春节想要买火车票回家,但是他工作很忙,因此他找了他的朋友小鹏帮他买票。
分析:这里小鹏就是一个代理。
public class 代理模式 { public static void main(String[] args) { Person xiaoMing = new Person(); proxy p = new proxy(xiaoMing); p.goToTrainStation(); p.buyTicket(); } } interface goBuyTicket { void goToTrainStation(); void buyTicket(); } class Person implements goBuyTicket { @Override public void goToTrainStation() { System.out.println("Go to the trainStation"); } @Override public void buyTicket() { System.out.println("Buy ticket"); } } class proxy implements goBuyTicket { private Person xiaoMing; public proxy(Person xiaoMing) { this.xiaoMing = xiaoMing; } @Override public void goToTrainStation() { xiaoMing.goToTrainStation(); } @Override public void buyTicket() { xiaoMing.buyTicket(); } }
不管是小明还是代理,他们都有能力去火车站买票,因此实现同一个买票接口。在代理中,放置被代理的对象。
(2)智能指引
例子:Smart Pointer,这在C++中十分常用,也十分powerful,特别是管理指针。
#include <iostream> #include <memory> using namespace std; class coo { public: void request() { cout << "coo request() " << endl; } ~coo() { cout << "coo destructor" << endl; } }; int main() { shared_ptr<coo> sp(new coo()); sp->request(); //可以像使用coo的指针一样 return 0; //自动释放coo(利用了sp是临时对象,会调用自己的析构函数) }
(3)安全代理
例子:系统管理员和普通用户的权限是不同的,比如修改root密码只有管理员能进行(管理员还能修改普通用户的密码),普通用户不能进行;而查看一些普通数据则全部用户都能进行。
#include <iostream> #include <string> using namespace std; class User { public: virtual string getName() { return "User"; } }; class NormalClient : public User { public: virtual string getName() { return "Normal client"; } }; class Root : public User { public: virtual string getName() { return "root"; } }; class Subject { public: virtual void changeRootPassword() = 0; virtual void viewNormalData() = 0; }; class OS : public Subject { public: //只有root能执行 void changeRootPassword() { cout << "修改管理员的密码" << endl; } //所有用户都能执行 void viewNormalData() { cout << "查看普通的数据" << endl; } }; class OSProxy : public Subject { public: OSProxy(User *user) { m_os = new OS(); m_user = user; } void setUser(User *user) { m_user = user; } void changeRootPassword() { if(m_user->getName() == "root") m_os->changeRootPassword(); else cout << "权限不够" << endl; } void viewNormalData() { m_os->viewNormalData(); } private: OS *m_os; User *m_user; }; int main() { cout << "以管理员身份操作" << endl; OSProxy *proxy = new OSProxy(new Root()); proxy->changeRootPassword(); proxy->viewNormalData(); cout << endl << "以普通用户身份操作" << endl; NormalClient *client = new NormalClient(); proxy->setUser(client); proxy->changeRootPassword(); proxy->viewNormalData(); }
(4)虚拟代理
例子:如果是获取类的名字,那么代理直接返回被代理者的名字,不需要马上实例化,如果是调用operation()方法才实例化被代理者。
#include <iostream> using namespace std; class Subject { public: virtual void getName() = 0; virtual void operation() = 0; }; class BigClass : public Subject { public: BigClass() { cout << "实例化已花费半小时" << endl; } virtual void getName() { cout << "BigClass" << endl; } virtual void operation() { cout << "利用实例来进行操作" << endl; } }; class Proxy : public Subject { public: //我们预先已知道getName的结果,不需要使用BigClass的实例 virtual void getName() { cout << "BigClass" << endl; } //直到调用operation()时才实例化BigClass virtual void operation() { if(m_bigClass == nullptr) m_bigClass = new BigClass(); m_bigClass->operation(); } private: BigClass *m_bigClass; }; int main() { Proxy *p = new Proxy(); p->getName(); p->operation(); delete p; }
小结:代理模式让我们编写类时只关注功能的实现,而其他一些细节,比如内存管理,访问控制等交给代理来做。
标签:
原文地址:http://www.cnblogs.com/programmer-kaima/p/4382892.html