← 返回首页
设计模式基础教程(二十一)
发表时间:2021-08-26 17:38:23
代理模式

1.代理模式

在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。

代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。

代理模式包含如下角色: - Subject: 抽象主题角色 - Proxy: 代理主题角色 - RealSubject: 真实主题角色

2.实例

某影星最近拍戏崴了脚,不能参与舞蹈演出,使用Java动态代理实现。

项目目录结构图如下:

明星接口类

public interface IStar {
    //唱歌
    void sing();
    //跳舞
    void dance();
}

著名明星类(真实主题角色)


public class FamousStar implements IStar {
    private String name;

    public FamousStar(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void sing() {
        System.out.println(getName() + "唱了一首歌");
    }
    @Override
    public void dance() {
        System.out.println(getName() + "跳了一支舞");
    }
}

明星代理类(代理主题角色)

public class StarProxy implements InvocationHandler {
    private Object object;
    public StarProxy (Object o){
        this.object = o;
    }

    private boolean runBefore(Method method){
        System.out.println("拦截到代理请求");
        if(method.getName().equals("dance")){
            System.out.println("明星脚受伤了,不能跳舞表演了");
            return false;
        }
        return true;
    }

    private void runAfter(Method method){
        System.out.println(method.getName() + "代理请求完毕");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(!runBefore(method))
            return null;
        Object result = method.invoke(object, args);
        runAfter(method);
        return result;
    }

}

测试类

public class Test {
    public static void main(String[] args) {
        IStar iStars = new FamousStar("刘德华");
        InvocationHandler handler = new StarProxy(iStars);
        IStar proxy = (IStar) Proxy.newProxyInstance(iStars.getClass().getClassLoader(), iStars.getClass().getInterfaces(), handler);
        proxy.dance();
        proxy.sing();
    }
}

运行结果:
拦截到代理请求
明星脚受伤了,不能跳舞表演了
拦截到代理请求
刘德华唱了一首歌
sing代理请求完毕