一、什么是代理模式?
在现实生活中,我们常常遇到这样的场景:由于某些原因,我们可能无法亲自完成某个任务,便会委托他人代为执行。在设计模式中,代理模式 就是用来解决这种"委托"问题的,它允许一个对象通过代理对象来控制对另一个对象的访问。
今天我们就通过一个简单的例子来讲解代理模式的应用场景:小明委托小亮送资料给老师。
代理模式(Proxy Pattern)是一种结构型设计模式,它通过引入代理对象来控制对某个对象的访问。代理对象可以在访问实际对象之前或之后进行一些额外的操作。代理模式可以帮助我们在不改变原有对象的情况下,为对象提供附加功能。
1.代理模式的角色
- **主题接口(Object):**存放任务的抽象接口
- 真实对象(Real Object):真正的执行任务的对象。
- 代理对象(Proxy):代理类,代替真实对象执行任务,并在必要时执行一些额外的操作。
- 委托者(Client):请求执行任务的对象,通常由客户端调用代理类来完成任务。
二、代理模式应用
假设小明有一份重要的资料需要交给老师,但由于某些原因,小明不能亲自送过去。于是,小明委托了小亮来代为送资料。
- 小明:需要将资料交给老师,无法亲自送达。
- 小亮:代理小明去送资料。
- 老师:实际接收资料的人。
在这个例子中,小明通过小亮来"代理"完成送资料的任务,而小亮在送资料之前可以做一些额外的操作(例如确认资料是否完整)。代理模式正是通过这种方式来实现任务的委托。
三、代理模式的类设计
我们将这个场景通过代码实现。下面是我们用 Java 语言实现的类设计。
1. 资料类 Document
资料类表示需要交给老师的资料,包含资料名称和内容。
java
public class Document {
private String name; // 资料名称
private String content; // 资料内容
public Document(String name, String content) {
this.name = name;
this.content = content;
}
public String getName() {
return name;
}
public String getContent() {
return content;
}
@Override
public String toString() {
return "资料名称: " + name + ", 内容: " + content;
}
}
2. 送资料接口 Delivery
定义一个接口 Delivery
,所有的送资料类都需要实现这个接口。
java
public interface Delivery {
void deliver(Document document); // 送资料的行为
}
3. 实际送资料的类 DeliveryService
DeliveryService
类实现了 Delivery
接口,并负责实际的送资料操作。
java
public class DeliveryService implements Delivery {
@Override
public void deliver(Document document) {
System.out.println("送资料给老师: " + document);
}
}
4. 代理类 DeliveryProxy
DeliveryProxy
类作为代理,负责在送资料之前进行一些额外的操作,比如确认资料是否完好。如果资料没有问题,代理会将任务委托给 DeliveryService
。
java
public class DeliveryProxy implements Delivery {
private DeliveryService deliveryService; // 代理类持有一个 `DeliveryService` 的引用
public DeliveryProxy() {
this.deliveryService = new DeliveryService(); // 实例化实际的送资料服务
}
@Override
public void deliver(Document document) {
System.out.println("代理检查:确认资料是否完好...");
// 代理类可以做一些额外的操作,比如验证资料
if (document.getContent().length() > 0) {
// 资料无误,代理继续执行送资料的任务
System.out.println("代理:资料确认无误,开始送资料...");
deliveryService.deliver(document); // 委托给实际送资料服务
} else {
System.out.println("代理:资料有问题,无法送达!");
}
}
}
5. 测试类 ProxyPatternTest
最后,我们编写一个测试类来验证代理模式的应用。
java
public class ProxyPatternTest {
public static void main(String[] args) {
// 模拟小明的资料
Document document = new Document("Java 教学资料", "内容:Java设计模式");
// 小明委托小亮送资料
Delivery proxy = new DeliveryProxy();
proxy.deliver(document);
// 假设资料为空的情况
Document brokenDocument = new Document("错误的资料", "");
proxy.deliver(brokenDocument); // 代理会检查并拒绝送达
}
}
四、代理模式的执行流程
在测试中,我们通过 ProxyPatternTest
类模拟了两次送资料的过程。
1.第一次送资料
- 代理类首先会检查资料是否完整。
- 如果资料没有问题,代理会将任务交给
DeliveryService
类来执行实际的送资料操作。
2.第二次送资料
- 代理类再次检查资料是否完整。如果资料为空,代理会直接拒绝送达。
3.执行输出:
代理检查:确认资料是否完好... 代理:资料确认无误,开始送资料... 送资料给老师: 资料名称: Java 教学资料, 内容: 内容:Java设计模式 代理检查:确认资料是否完好... 代理:资料有问题,无法送达!
五、代理模式的优势与应用场景
1.代理模式的优势
- 增强功能:通过代理对象可以在不修改原始对象的情况下,增强其功能。
- 延迟加载:代理对象可以控制是否要真正加载或执行某些操作,节省资源。
- 灵活控制:代理对象可以控制真实对象的访问,进行权限管理或其他额外操作。
2.应用场景
- 延迟加载:例如图片、视频的加载,只有在需要时才加载资源。
- 虚拟代理:例如,显示大量数据时,只在用户滚动到相应位置时才加载数据。
- 远程代理:在分布式系统中,代理类可以作为客户端与远程服务之间的中介。
- 保护代理:代理类可以控制对真实对象的访问,例如权限控制、身份认证等。
六、总结
代理模式是一种结构型设计模式,它通过引入代理对象来控制对真实对象的访问。在我们的例子中,小明委托小亮送资料给老师,小亮作为代理类,在送资料之前可以做一些额外的操作,比如确认资料的完整性。通过代理模式,我们能够增强任务的功能而不修改实际执行任务的对象。
代理模式非常适合需要控制访问、增强功能或延迟加载的场景。如果你在项目中有类似需求,可以考虑使用代理模式。
希望这篇博客能够帮助你更好地理解代理模式的应用!如果有任何问题,欢迎随时在评论区留言或私信我。