简介:
代理模式,它是一种结构型设计模式,它通过引入一个代理对象来控制对原始对象的访问。代理模式的主要目的是在保持原始对象完整性的同时,提供对原始对象的访问和控制。
代理模式包括以下三个角色:
抽象主题类(Subject):通过接口或抽象类声明真实主题和代理对象实现的业务方法。
真实主题类(Real Subject):实现抽象主题中的具体业务,是代理对象所代表的真实对象,是最终引用的对象。
代理类(Proxy):提供与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
在代理模式中,代理对象充当访问对象和目标对象之间的媒介,通过代理对象实现对目标对象的访问。被代理的对象可以是远程对象、创建开销大的对象以及需要安全控制的对象。
代理模式可以按照代理的生成时机不同分为静态代理和动态代理。静态代理在编译期就生成代理对象,而动态代理则是在Java运行时动态生成。动态代理又分为JDK动态代理和Cglib动态代理两种。
使用代理模式可以带来很多好处,例如可以控制对原始对象的访问,可以在调用真实对象之前或之后执行一些操作,可以扩展真实对象的功能,可以提供更复杂的接口等。
总之,代理模式是一种非常有用的设计模式,可以帮助我们更好地设计和实现软件系统。
代理模式的使用场景:
1、保护目标对象:客户端只与代理类进行交互,不清楚目标对象的具体细节。这可以保护目标对象不被直接访问,增强了安全性。
2、增强目标对象:代理类可以在目标对象的基础上,对目标对象的功能进行增强。代理对象可以扩展目标对象的功能,实现额外的操作。
3、分离目标对象:代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性。这种分离使得客户端和目标对象的交互更加清晰和灵活。
以上场景中,代理模式通过在客户端和目标对象之间增加一个代理对象,实现对目标对象的访问和控制。代理对象可以提供与目标对象相同的接口,并且内部含有对目标对象的引用,通过代理对象实现对目标对象的访问和控制。
代理模式的创建步骤:
1、定义一个接口,该接口定义了目标对象的所有方法。
2、创建目标对象,实现接口中定义的所有方法。
3、创建代理对象,该对象需要实现与目标对象相同的接口,并在内部持有对目标对象的引用。
4、在代理对象中,重写目标对象的所有方法,并在调用目标对象之前或之后执行一些操作。
5、在客户端代码中,使用代理对象代替目标对象进行操作。
以上步骤是代理模式的基本创建过程,具体实现方式可能会因语言和框架的不同而有所差异。在实际开发中,可以根据具体情况进行调整和优化。
代理模式的优点,主要包括:
1、职责清晰:真实的角色实现实现的业务逻辑,不用关心其他非本职的事务,通过后期的代理完成附件的事务,附带的结果就是编程简洁清晰。
2、高度扩展性:具体主题角色随需求不同可能变为多种,但是只要实现了接口,代理类就可以完全在不做任何修饰的情况下代理各种真实的角色。
3、智能化:代理类可以再运行的时候确定真实的代理主题,这是一种强大的功能。
4、保护目标对象:代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。同时,代理对象可以在调用真实对象之前或之后执行一些操作,增强了程序的灵活性和可扩展性。
代理模式的缺点,主要包括:
1、代理对象可能会造成请求的处理速度变慢。由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作。有些代理模式的实现非常复杂,需要编写更多的代码和测试用例来确保代理对象和真实对象之间的通信和交互是正确的。
3、代理对象可能会对真实对象进行过度的控制,使得真实对象无法被正确地使用。
4、在代理模式中,客户端需要知道代理对象的类型和接口,这可能会破坏封装性,使得代码变得不够灵活。
总之,虽然代理模式具有许多优点,但是也有一些缺点需要注意。在使用代理模式时,需要根据具体的应用场景和需求来权衡利弊,并选择合适的代理模式来实现所需的功能。
示例:
一、C#代理模式
以下是一个示例,展示了如何在C#中实现代理模式:
public interface ISubject {
void DoSomething();
}
public class RealSubject : ISubject {
public void DoSomething() {
Console.WriteLine("RealSubject.DoSomething()");
}
}
public class Proxy : ISubject {
private ISubject _subject;
public Proxy(ISubject subject) {
_subject = subject;
}
public void DoSomething() {
Console.WriteLine("Proxy.DoSomething()");
_subject.DoSomething();
}
}
class Program {
static void Main(string[] args) {
ISubject subject = new RealSubject();
Proxy proxy = new Proxy(subject);
proxy.DoSomething(); // Output: Proxy.DoSomething() RealSubject.DoSomething()
}
}
二、java代理模式
代理模式通常通过以下方式实现:
interface Subject {
void doSomething();
}
class RealSubject implements Subject {
public void doSomething() {
System.out.println("RealSubject.doSomething()");
}
}
class Proxy implements Subject {
private Subject _subject;
public Proxy(Subject subject) {
_subject = subject;
}
public void doSomething() {
System.out.println("Proxy.doSomething()");
_subject.doSomething();
}
}
public class ProxyPatternDemo {
public static void main(String[] args) {
Subject subject = new RealSubject();
Proxy proxy = new Proxy(subject);
proxy.doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()
}
}
三、javascript代理模式
在JavaScript中,代理模式的实现方式如下:
class Subject {
constructor() {
this._data = [];
}
addData(data) {
this._data.push(data);
}
getData() {
return this._data;
}
}
class Proxy {
constructor(subject) {
this._subject = subject;
}
addData(data) {
console.log('Proxy.addData()');
this._subject.addData(data);
}
getData() {
console.log('Proxy.getData()');
return this._subject.getData();
}
}
const subject = new Subject();
const proxy = new Proxy(subject);
proxy.addData('data1'); // Output: Proxy.addData() [ 'data1' ]
proxy.getData(); // Output: Proxy.getData() [ 'data1' ]
四、C++代理模式
以下是在C++中实现代理模式:
class Subject {
public:
virtual void doSomething() = 0;
};
class RealSubject : public Subject {
public:
void doSomething() override {
std::cout << "RealSubject.doSomething()" << std::endl;
}
};
class Proxy : public Subject {
public:
Proxy(Subject* subject) : _subject(subject) {}
void doSomething() override {
std::cout << "Proxy.doSomething()" << std::endl;
_subject->doSomething();
}
private:
Subject* _subject;
};
int main() {
RealSubject* realSubject = new RealSubject();
Proxy* proxy = new Proxy(realSubject);
((Subject*)proxy)->doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()
delete proxy;
delete realSubject;
return 0;
}
五、python代理模式
以下是在python中实现代理模式:
class Subject:
def do_something(self):
pass
class RealSubject(Subject):
def do_something(self):
print("RealSubject.do_something()")
class Proxy(Subject):
def __init__(self, real_subject):
self._real_subject = real_subject
def do_something(self):
print("Proxy.do_something()")
self._real_subject.do_something()
if __name__ == "__main__":
real_subject = RealSubject()
proxy = Proxy(real_subject)
proxy.do_something() # Output: Proxy.do_something() RealSubject.do_something()
六、go代理模式
以下是一个示例,展示了如何在go中实现代理模式:
type RealObject struct{}
func (r *RealObject) Operation() {
fmt.Println("RealObject.Operation()")
}
type ProxyObject struct {
realObj *RealObject
}
func (p *ProxyObject) Operation() {
fmt.Println("ProxyObject.Operation()")
p.realObj.Operation()
}
func main() {
realObj := &RealObject{}
proxyObj := &ProxyObject{realObj: realObj}
proxyObj.Operation() // Output: ProxyObject.Operation() RealObject.Operation()
}
七、PHP代理模式
以下是一个示例,展示了如何在PHP中实现代理模式:
<?php
// 目标接口
interface Subject {
public function doSomething();
}
// 目标类
class RealSubject implements Subject {
public function doSomething() {
echo "RealSubject.doSomething()";
}
}
// 代理类
class Proxy implements Subject {
private $realSubject;
public function __construct(RealSubject $realSubject) {
$this->realSubject = $realSubject;
}
public function doSomething() {
echo "Proxy.doSomething()";
$this->realSubject->doSomething();
}
}
// 客户端代码
$realSubject = new RealSubject();
$proxy = new Proxy($realSubject);
$proxy->doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()
《完结》