分栏目录
文章目录
阐述
结构性模式之一,通过引入一个代理对象来控制对原对象的访问;代理对象在客户端和目标对象之间充当中介,在转发请求给目标对象前后进行额外的处理,且不影响原功能
一、与装饰器模式的主要区别
由于代理模式作为中介进行额外处理的方式和装饰器非常相似,故在此做比较处理
1、强调方向不同:装饰器主要用于增强功能,代理主要强调代理访问,隔离对原对象的直接访问
换句话说,装饰器通常在控制访问时有增强功能,而代理不一定有,它重在替代访问,隔离就算完成任务
2、对象数量不同:装饰器通常指装饰某单一对象,代理模式更倾向于代理多数有同种需求的对象,由点到面形成切面,这也是为什么在学习时看到几乎所有资料都说AOP切面使用的是代理模式的原因;补充,AOP切面的最常见应用就是日志增强,这里顺便把日志增强作为例子来说明这一点:通常我们是把多个有日志打印需求的类都进行处理,而打印是完全相同的动作,每一个需要处理的类都是一个点,由点到面,故而叫切面,在原功能前后同一进行日志增强(打印)
二、实际应用场景
不要重理论要重实践喔,以前学习的时候我也老看不起应用场景,或者说经常看到大而空的场景应用就不想看,实际上反而这一点才是进到项目里最常用的
我也就做个列举,哈哈,大概这也是以前为什么看到就跳过的原因,大家都一样,因为应用场景要展开来说就太多了,你不想看我不想写
1、AOP切面
2、日志增强
3、事务管理
4、安全检查
5、权限控制
三、案例代码
1、目标接口(Target)的实现
// 目标接口
interface Target {
void request();
}
- 分析:这个接口定义了非常简单的
request
方法,它是客户端对电源操作的抽象。任何实现这个接口的类都需要提供request
方法的具体实现,以满足客户端的期望,这为适配器类和其他可能的电源实现提供了统一的接口规范1。
2. 被适配者(Adaptee)的实现 - 代码片段
// 被适配的类
class Adaptee {
void specificRequest() {
System.out.println(" 使用美国电源(110V)");
}
}
- 分析:
Adaptee
类是被适配的美国电源类,它有自己的specificRequest
方法,该方法表示提供美国电源(110V)的操作。这个类是原有的、不符合客户端直接需求的类,需要通过适配器进行适配。
3. 适配器(Adapter)的实现 - 代码片段
// 适配器类
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
System.out.println(" 适配为中国电源(220V)");
}
}
- 分析
- 首先,适配器类
Adapter
实现了目标接口Target
,这使得它可以被客户端当作目标接口类型来使用。 - 它内部持有一个
Adaptee
类型的私有成员变量adaptee
,通过构造函数注入被适配者实例。 - 在
request
方法中,先调用被适配者的specificRequest
方法来执行原有的美国电源操作,然后再输出适配为中国电源(220V)的操作,从而将被适配者的功能适配到目标接口的规范下。
- 首先,适配器类
4. 客户端(Client)的实现 - 代码片段
// 客户端类
class Client {
public void usePower(Target target) {
target.request();
}
}
- 分析:客户端类
Client
的usePower
方法接受一个Target
类型的参数,这体现了客户端只依赖于目标接口而不依赖于具体的实现类。在main
方法中,创建了美国电源实例americanPower
、适配器实例adapter
和客户端实例client
,然后通过客户端调用usePower
方法并传入适配器实例,这样就完成了整个适配过程,使得客户端能够使用经过适配后的美国电源,就好像它是符合中国电源标准的一样。