介绍
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理对象起到了中介的作用,通过代理对象来访问实际的对象,从而达到对实际对象的控制和管理。
代理模式在软件开发中应用非常广泛,例如远程代理、虚拟代理、保护代理、智能引用等,它们都是代理模式的具体应用。代理模式可以有效地解决对象的访问问题,提高代码的灵活性和可维护性,同时也可以提高代码的复用性和可扩展性。
模式结构
代理模式主要包含以下角色:
- 抽象主题(Subject):定义了真实主题和代理主题的公共接口,可以是抽象类或接口。
- 真实主题(Real Subject):定义了代理所代表的真实对象,是代理模式中实际执行业务逻辑的类。
- 代理主题(Proxy Subject):保存一个引用使得代理可以访问实体,并提供一个与真实主题相同的接口,从而可以代替真实主题。
实现方式
代理模式的实现方式有两种:
- 静态代理:由程序员创建或工具生成代理类的源码,在对其进行编译后便可以使用代理类。
- 动态代理:通过使用JDK自带的Proxy类或者第三方工具库(如CGLib)在程序运行时动态生成代理类的源代码。
在实现代理模式时,我们首先需要定义抽象主题和真实主题,然后定义代理主题,最后在客户端中使用代理主题来访问真实主题。
代码示例
下面我们以静态代理为例来实现一个简单的代理模式。我们定义抽象主题Shape,并实现两个具体的形状Circle和Rectangle。然后定义代理主题ShapeProxy,它持有一个真实主题的引用,并实现了与真实主题相同的接口。最后在客户端中使用代理主题来访问真实主题。
Shape.java:
代码语言:javascript复制public interface Shape {
void draw();
}
Circle.java:
代码语言:javascript复制public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}
Rectangle.java:
代码语言:javascript复制public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
}
ShapeProxy.java:
代码语言:javascript复制public class ShapeProxy implements Shape {
private Shape shape;
public ShapeProxy(Shape shape) {
this.shape = shape;
}
@Override
public void draw() {
System.out.println("Before drawing...");
shape.draw();
System.out.println("After drawing...");
}
}
Client.java:
代码语言:javascript复制public class Client {
public static void main(String[] args) {
Shape circle = new Circle();
Shape rectangle = new Rectangle();
ShapeProxy circleProxy = new ShapeProxy(circle);
ShapeProxy rectangleProxy = new ShapeProxy(rectangle);
circleProxy.draw();
rectangleProxy.draw();
}
}
输出结果为:
代码语言:javascript复制Before drawing...
Drawing Circle
After drawing...
Before drawing...
Drawing Rectangle
After drawing...
在上面的示例中,我们通过代理主题ShapeProxy来代替真实主题Circle和Rectangle来执行draw()方法。在代理主题的draw()方法中,我们先输出一句话表示执行前的操作,然后再调用真实主题的draw()方法,最后再输出一句话表示执行后的操作。
通过上面的示例,我们可以看出代理模式的作用,它可以在不改变原有代码的情况下,对真实主题进行控制和管理。在上面的示例中,我们在真实主题执行前后添加了额外的操作,从而达到对真实主题的控制。如果我们需要对真实主题进行其他操作,只需要在代理主题中添加相应的代码即可。