目录
八、设计模式之代理模式
又叫: 委托模式
所属类型 | 定义 |
---|---|
结构型 | 为其他对象提供一种代理以控制该对象的访问 |
能帮我们干什么?
主要解决什么问题?
主要解决的是 在直接访问对象时带来的问题
优缺点
优点
- 对对象进行访问控制
- 职责清晰。
- 高扩展性。
- 智能化。
动态代理
缺点:
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能存在请求的处理速度变慢。
- 需要额外的工作,有些代理模式的实现非常复杂。
使用的场景
- 想在访问一个类时做一些控制。
角色
代理模式包含以下3个角色。
-
Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。
-
Proxy(代理主题角色):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;在代理主题角色中提供了一个与真实主题角色相同的接口,以便任何时候都可以代替真实主题;代理主题角色还可以控制真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。
通常,在代理主题角色中客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅单纯调用真实主题对象中的操作。
-
RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接使用真实主题角色中定义的操作。
实现
代理模式
代理类和主题类是实现同一个主题,代理类持有一个主题类。
实现难度: ⭐️
/**
* 抽象功能接口
*/
public interface Subject {
public void ability();
}
public class SubjectImpl implements Subject {
@Override
public void ability() {
System.out.println("盖恒大的房子");
}
}
/**
* 能力的代理类
*/
public class SubjectProxy implements Subject {
private SubjectImpl subject;
public SubjectProxy(SubjectImpl subject){
this.subject = subject;
}
@Override
public void ability() {
System.out.println("检查权限是否合法");
subject.ability();
}
}
【扩展】: 普通代理
要求客户端只能访问代理对象,不能访问真实角色
【扩展】:强制代理模式
只有真实角色创建的代理类才可以访问,其他创建的都不能访问。
理解:正常都是先创建代理类,在创建真实角色类。
强制: 创建真实模式时,返回的是代理类
【扩展】:代理是有个性的
通过对个性接口的实现,可以增强目标类的方法,但这种增强是通过拦截和过滤进行增强。如 执行前,执行后,过滤消息,消息转发等过程控制型增强。
【扩展】 : 虚拟代理
在代理方法中,判断真实主题是否存在,不存在创建真实主题对象
按需要时初始化真实对象,即 虚拟代理
【扩展】:动态代理 【重要】
在实现阶段不需要知道代理谁,在运行时确认代理的真实主题。
现在流行的面相切面编程 AOP,其实质就是采用了动态代理机制。
java里实现了动态代理,使用Proxy即可创建动态代理,但是java中的动态代理只能代理接口,不能代理类。
cglib工具可以动态代理代理类。
只需要有一个接口和一个实现类,就可以动态 创建该实现类的代理类。
// 一个接口和一个实现类
Subject subject = new Subject() {
@Override
public void say() {
System.out.println("我是真实的主题对象");
}
};
// 动态代理处理器
SubjectHandler dynamicProxyHandler = new SubjectHandler(subject);
// 创建代理类
Subject o = (Subject) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Subject.class}, dynamicProxyHandler);
// 调用通用方法
o.say();
总结
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
3、 代理模式的变化形式非常多,常见的代理形式有远程代理、保护代理、虚拟代理、缓冲代理、智能引用代理等