1.简述
代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
2.角色
- Subject:抽象主题角色。可以是接口,也可以是抽象类,是一个最普通的业务类型定义,无特殊要求。
- RealSubject:具体主题角色,也叫做被委托角色、被代理角色。业务逻辑的具体执行者。
- ProxySubject:代理主题角色,也叫做委托类、代理类。内部含有RealSubject的引用,负责对真实角色的调用,并在真实主题角色处理前后做预处理和善后工作。
3.UML类图
4.通用代码
//抽象主题类
interface Subject {
// 定义了一个方法
public void request();
}
//真实主题类
class RealSubject implements Subject {
// 实现方法
public void request() {
// 业务处理
}
}
//代理类
class Proxy implements Subject {
// 要代理哪个实现类
private Subject subject = null;
public Proxy(Subject subject) {
this.subject = subject
}
// 实现接口中定义的方法
public void request() {
this.before();
this.subject.request();
this.after();
}
// 预处理
private void before() {
// do something
}
// 善后处理
private void after() {
// do something
}
}
5.举例说明
例如你要买一个口红,然后你又不想自己买,你就可以找个代购帮你买。
买口红--接口 真实主题:你 代理类:代购
//抽象主题类
interface Ilipstick {
void buyLipstick();
}
//真实主题类
class RealSubject implements Ilipstick {
public void buyLipstick() {
System.out.println("买口红!");
}
}
//代理类
class Proxy implements Ilipstick {
// 代理所要实现的哪个类
private RealSubject subject = null;
// 通过构造函数传递代理者
public Proxy(RealSubject subject) {
this.subject = subject;
}
public void before() {
System.out.println("取钱,排队!");
}
// 实现接口中定义的方法
public void buyLipstick() {
this.before();
subject.buyLipstick();
this.after();
}
public void after() {
System.out.println("邮递,结束!");
}
}
public class Test {
public static void main(String[] args) {
Proxy myProxy = new Proxy(new RealSubject());
myProxy.buyLipstick();
}
}
结果如下:
取钱,排队!
买口红!
邮递,结束!
6.代理模式优点
- 职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职务的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。
- 高扩展性:具体主题角色是随时都会变化的,只要它实现了接口,甭管它如何变化,都逃不出如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用
7.代理模式的缺点
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
8.代理模式适用场景
- 当我们想要隐藏某个类时,可以为其提供代理类
- 无法或者不想直接访问某个对象时可以通过一个代理对象来间接的访问。