代理模式,用一个类来表示另外一个类的功能。所谓“代理”,即为“经纪人”。由于某些原因,用户不可以直接访问原始的类,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。代理模式可以为其他对象提供一种代理以控制对这个对象的访问。
代理可以理解为经纪人,经纪人可以新增些特有的操作,而不用去修改原有对象。而且,用户可以通过访问经纪人的方式,避免直接访问对象,从而保证了程序结构的安全性。
例如 :新增存款账户类,存折和银行卡继承存款账户类。
//存款账户抽象类
class DepositAccount{
public:
virtual void save(double money); //存钱
virtual void withdraw(double money); //取钱
}
// 存折类
class Bankbook:public DepositAccount {
private:
string bookAccounts; //存折账号
string bookPassword; //存折密码
double deposit; //存款
public :
void save(double money){
/*....存折账户上累加存款金额.....*/
deposit +=money;
}
void withdraw(double money){
/*验证账户安全操作*/
......
/*....存折账户上累减取款金额.....*/
deposit -=money;
}
}
// 银行卡类
class BankCard:public DepositAccount {
private:
string cardAccounts; //存折账号
string cardPassword; //存折密码
double deposit; //存款
public :
void save(double money){
/*.... 银行卡账户上累加存款金额.....*/
deposit +=money;
}
void withdraw(double money){
/*验证账户安全操作*/
......
/*.... 银行卡上累减取款金额.....*/
deposit -=money;
}
}
由于某些原因,不可以直接访问存折和银行卡对象,只能访问它们的代理类:支票对象
// 支票代理类
class Check:public DepositAccount {
private:
DepositAccount* depositAccount ; //存款账号对象
double money_;
void save(double money){
depositAccount.save(money);
}
void withdraw(double money){
depositAccount.withdraw(money);
}
public :
Check(DepositAccount & depositAccount,double m){
this->depositAccount =depositAccount ;
this->money_=m;
}
//转账操作
void transfer(DepositAccount targetAccount){
depositAccount->withdraw(money_);
targetAccount.save(money_);
//新增给目标账户发短信...
sendmail(targetAccount);
}
//直接存款
void save(){
this->save(money_);
}
//直接取款
void withdraw(){
this->withdraw(money_);
}
}
外部主程序访问操作:
void mainProcess(DepositAccount & depositAccount ){
//可以不用关心传进来的DepositAccount是存折还是银行卡,都可以用支票类完成功能
//并且可以避免直接访问存款账户,提高系统结构的安全性
Check withdrawCheck (depositAccount,2000000);
withdrawCheck.withdraw();
}
动态代理可以代理多种不同类但是同父类的对象,通过访问“中介”,由“中介”间接访问实际对象。提高系统结构的扩展性 ,系统结构职责更加清晰等。代理模式属于对象结构型模式。