AkiraZheng's Time.

设计模式4:代理模式(C++)

Word count: 985Reading time: 3 min
2024/02/02

前言

本文中所有设计模式Github代码
其中本文代理模式相关代码在ProxyPattern.h文件中

一、代理模式基础

1. 代理模式的使用场景

当某些对象由于某些原因,不能直接访问另一个对象,需要通过一个代理对象来间接访问时,可以使用代理模式。

某些原因指的是比如:对象创建的开销大、某些操作需要安全控制、需要访问进程外的对象等。

分布式系统中,代理模式的使用极其广泛,例如在分布式系统中,客户端和服务器端的交互,客户端无法直接访问服务器端的对象,需要通过代理对象来访问服务器端的对象。

2. 代理模式的定义

代理模式是一种结构型设计模式,它可以为其他对象提供一种代理以控制对这个对象的访问

代理类和被代理类有相同的接口(继承同一个基类),代理类主要负责为被代理类预处理消息、过滤消息、把消息转发给被代理类,以及事后处理消息等。

二、代理模式的实现(C++)

在没有使用代理模式时,Client有一个需求是需要new一个RealSubject对象,然后调用其方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Isubject{
// 抽象基类
public:
virtual void Request() = 0;
};
class RealSubject:public Isubject{
// 真实主题类
public:
void Request(){
cout << "RealSubject::Request()" << endl;
}
};
class Client{
Isubject* _subject;
// 客户端
public:
Client(){
_subject = new RealSubject();//客户端需要使用一个RealSubject对象
}
void DoTask(){
_subject->Request();
}
};

从上面的代码中中,我们可以看到,Client需要new一个RealSubject对象,然后调用其方法。但是由于某些原因,Client是无法实现直接new一个RealSubject对象

那么这个时候需要通过一个代理对象Proxy来间接访问RealSubject对象

在代理模式中,代理类Proxy被代理类RealSubject继承自同一个基类Isubject,这样可以保证代理类和被代理类有相同的接口。Proxy就可以在这个接口上实现对RealSubject的一系列代理操作

Proxy在这个接口上可以创建一个RealSubject对象,然后调用其方法,Client通过Proxy来间接访问RealSubject对象;也可能在如分布式的场景下,Proxy在这个接口上可以通过网络访问RealSubject对象,然后调用其方法,Client通过Proxy来间接访问RealSubject对象。因此Proxy这个接口的实现方式是复杂多变的,这里介绍设计模式,因此将其简化了,旨在理解它的实现流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Isubject{
// Proxy和RealSubject共同继承的抽象基类
virtual void Request() = 0;
}

class RealSubject:public Isubject{
// 真实主题类
public:
void Request(){
cout << "RealSubject::Request()" << endl;
}
};

class Proxy:public Isubject{
// 代理类
public:
void Request(){
//实现一系列复杂的代理操作,来对RealSubject进行访问
//有些框架会用自动工具来生成代理
//不同代理类的内部实现粒度和方法都是相差很大的,但是具体实现思想是一致的(Proxy和RealSubject用相同的接口)
}
}

class Client{
Isubject* _subject;
public:
Client(){
_subject = new Proxy();//客户端需要使用一个Proxy对象
}
void DoTask(){
_subject->Request();//通过Proxy类间接访问RealSubject对象
}
}

这里Proxy和RealSubject共同继承的抽象基类Isubject,以通过同一个接口名的接口来实现Client实际想实现的对RealSubject的访问操作,好处是Client不用同时记住代理类和实际类的接口名,只需要知道抽象类的接口名就行,这种方法可以使客户端感觉是在对RealSubject进行操作。这种设计也是符合设计模式的开闭原则的,即对扩展开放,对修改关闭。

CATALOG
  1. 前言
  2. 一、代理模式基础
    1. 1. 代理模式的使用场景
    2. 2. 代理模式的定义
  3. 二、代理模式的实现(C++)