目录
Java代理模式(1)一静态代理
Java代理模式(2)一动态代理
前言
有一天,小李在项目中发现一个严重的问题,需要直接向其他部门的经理B沟通该问题。但是想来想去,出于职场经验小李决定不能直接去找那个经理,不能越过自己部门领导而直接去找。这样违反了职场规则。那么小李最后决定先找部门负责该项目的领导A,然后请求领导A向经理B反映沟通该问题。
这个例子中涉及到我们的代理模式,何为代理模式呢,从小李请求沟通这方面讲:
1、小李作为被领导A代理对象,他的所有问题都会反映给经理B。
2、项目领导A,会代表小李把所有的问题反映给经理B
3、小李与领导A都是一个同一部门的,都是为一个项目努力工作的。
一、代理模式相关概念
1、为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
2、通过代理对象可以实现对委托对象(被代理对象)隐蔽与保护目的,同时因为实现了同一个接口的结果,代理类与被代理类实现了一致性。并且代理对象还可以进行灵活的扩展,不再害怕破坏原有功能模块。
代理模式涉及三个角色信息:
- 抽象角色:声明真实对象和代理对象的共同接,为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。
- 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
- 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
代理模式的UML图如下:
其中:
Subject
方法是代理对象Proxy
与真正被代理的对象RealSubject
的共同接口Proxy
帮助对象代理RealSubject
,在内部实现其RealSubject
的方法Request()
,包含了对RealSubject
的引用。而在Proxy
对象中客户不光只是简单调用RealSubject
,还可能会涉及更多的实际业务操作,都可以在Proxy
中扩展。
二、代码举例实现
以小李的问题举例简单实现Java代理模式
Subject
:小李与领导A共同重视的问题,都需要先去认识这个问题并一致提出解决方案
/**
* 领导A与小李都是所做的一切都是为了沟通解决问题的
* @author Lijian
*
*/
public interface ProblemInterface {
void resolve();//解决问题
}
RealSubject
:小李有问题要反映,但是不能直接找经理B
/**
* 小李将问题都说领导A
* @author Lijian
*
*/
public class RealSubject implements ProblemInterface{
@Override
public void resolve() {
System.out.println("There is an fatal bug in xxx project, It mainly includes...");//小李有问题反映
}
}
Proxy
:领导A将小李反映的问题整理,然后做好沟通经理B的前后工作
package proxy;
/**
* 领导A代理小李沟通解决问题
* @author Lijian
*
*/
public class Proxy implements ProblemInterface{
private ProblemInterface problemInterface = new RealSubject();//领导A已经与小李取得联系
@Override
public void resolve() {
System.out.println("I'm preparing for it");//领导A先准备好材料
problemInterface.resolve();//开始与经理B沟通反映
System.out.println("In a word, I think the problem...");//结束后领导A做了总结
}
}
Client
:经理B也做好了与领导A的沟通准备,取得了领导A的联系
/**
* 经理B请求与领导A沟通一起解决问题
* @author Lijian
*
*/
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.resolve();
}
}
最后领导A顺利将问题反映给经理B,以下是A代理小李反映问题给经理B的过程:
I'm preparing for it
There is an fatal bug in xxx project, It mainly includes...
In a word, I think the problem...
以上就是其实就是Java三种模式(静态代理,动态代理,CGLib代理)中的静态代理。静态代理的缺点很明显:
- 必须要通过开发人员手动去实现接口并调用的;
- 只能一个代理类实现一个接口,如果接口中的还有未实现的方法时,代理类也要必须实现。同时会产生大量重复的代码。
为此我们必须使用Java的另一种代理方式来进一步完善Java代理模式(2)一动态代理