代理模式(结构型)

2018-10-04  本文已影响6人  游牧族人

定义:
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
代理对象可以代替目标对象实现目标对象的方法,同时可以对目标对象的方法进行增强处理。
三个角色:
抽象目标对象:目标对象的抽象表现形式。
具体目标对象:实现了抽象目标对象的具体目标对象。
代理目标对象:实现了抽象目标对象,同时作为具体目标的代理对象。

静态代理:

// 抽象行为
public interface Action
{
    void play();
    void work();
}
// 具体目标对象
public class Person implements Action
{
    @Override
    public void play()
    {
        System.out.println("开始游戏");
    }

    @Override
    public void work()
    {
        System.out.println("开始工作");
    }
}
// 代理目标对象
public class PersonProxy implements Action
{
    private Person person;

    public PersonProxy(Person person)
    {
        this.person = person;
    }

    @Override
    public void play()
    {
        System.out.println("play 拦截");
        person.play();
    }

    @Override
    public void work()
    {
        System.out.println("work 拦截");
        person.work();
    }
}
// 客户端
public class Client
{
    public static void main(String[] args)
    {
        Person person = new Person();
        PersonProxy personProxy = new PersonProxy(person);

        personProxy.play();
        personProxy.work();
    }
}
Output:
play 拦截
开始游戏
work 拦截
开始工作

动态代理:
在程序运行过程中通过反射机制动态创建代理类。

//  JDK 动态代理
public class Client{
    public static void main(String[] args){
        Action action = new Person();
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) 
                    throws Throwable {
                if(method.getName().equals("play")){
                    System.out.println("play 拦截");
                }
                if(method.getName().equals("work")){
                    System.out.println("work 拦截");
                }

                Object o = method.invoke(action,args);
                return o;
            }
        };
        Action proxy = (Action) Proxy.newProxyInstance(
                action.getClass().getClassLoader(), 
                action.getClass().getInterfaces(),
                invocationHandler);

        proxy.play();
        proxy.work();
    }
}
Output:
play 拦截
开始游戏
work 拦截
开始工作
上一篇下一篇

猜你喜欢

热点阅读