两个子类共同实现一个接口,其中一个子类负责实现正真的业务,另一个子类完成辅助真正业务主题的操作
可以实现对真正内容的扩展,而不需要真正内容的改变
代理模式的本质:所有的真实业务操作都会有一个与之辅助的工具类(功能类)共同完成。
代理模式在JavaEE中有着广泛的应用。EJB、WebService,Spring等技术都是代理模式的应用
代理实现模式很好的实现了开闭原则,比如说捏人有一个类,但是功能不够,你想添加功能,就必须修改,但是这样违背了开闭原则,这是可以选择代理模式。
应用:Runnable Thread类实现了Runnable,自己写的线程类也实现了Runnable
代理设计模式的专业名词:
Subject 代理接口 真正的业务逻辑和代理类都要实现这个接口
RealSubject 业务类
ProxySubject 代理类
New RealSubject() 目标对象,被代理对象
New ProxySubject(subject) 代理对象
代理模式就像是补救措施(对一个已有类进行扩展,发现java中的某一个类不再满足自己的需求,想要扩展。)
1、原类不是自己写的(Java源码),没办法进行修改,
2、如果被final修饰,就没办法进行继承,
3、方法被final修饰,不能覆写,
这事就对他无能为力,寻找机会,看他有没有实现某个接口,你也写一个类实现它的接口,并将他的实例化对象传进去,然后再方法中对他进行扩展(如果没有公共的接口,可以直接将类传入,假装写一个名字一样的类,也可以达到扩展的目的)
public class ProxyTest{
public static void main(String[] args){
Subject realSubject = new RealSubject();
Subject proxySubject = new ProxySubject(realSubject);
proxySubject.buyComputer();
}
}
interface Subject{
void buyComputer();
}
class RealSubject implements Subject{
public void buyComputer(){
System.out.println("买电脑");
}
}
class ProxySubject implements Subject{
private Subject target;;//一般为接口类型,不然代理类会和业务类耦合
public ProxySubject(Subject target){
this.target=target;
}
public void buyComputer(){
System.out.println("生产电脑");
this.target.buyComputer();
System.out.println("售后服务");
}
}
一个接口,1个真实类,1个代理类
缺陷:N个接口,N个真实类,N个代理类
所以有了动态代理模式
动态代理:代理类不再实现某一具体接口,而是要实现InvocationHandler接口,只有实现了InvocationHandler接口的类才具备了动态代理的功能
1个接口,N个真实类,N个代理类
动态代理实现的标识接口,只有实现此接口才具备有动态代理的功能
public interface InvocationHandler {
/** invoke表示的是调用执行的方法,但是所有的代理类返回给用户的接口对象都属于代理对象
当用户执行接口方法的时候所调用的实例化对象就是该代理主题动态创建的一个接口对象
@param proxy 表示被代理的对象信息
@param method 返回的是被调用的方法对象,取得了Method对象则意味着可以使用invoke()反射调用方法
@param args 方法中接收的参数
@return 方法的返回值
@throws Throwable 可能产生的异常*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}