设计模式 代理模式

来源:互联网 发布:手机平面设计软件 编辑:程序博客网 时间:2024/05/22 03:24

定义

即Proxy Pattern,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

角色组成

抽象角色

通过接口或抽象类声明真正角色实现的业务方法

代理角色

实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作

真实角色

实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用

模式结构

一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理对象,在访问真正的对象。

优点

1、职责清晰
真正的角色就是实现实际的业务逻辑,不用关心其他非本职责的实物,通过后期的代理完成一件完成事物,附带的结果就是编程简洁清晰
2、代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护目标对象的作用
3、高扩展性

分类

分为五静态代理模式和动态代理模式,我们从代码的角度来理解这两种代理模式

静态代理模式

1、真实角色和代理对象的共同接口

/** * 真实对象和代理对象的共同接口 * */public abstract class Subject {    public abstract void request();}

2、真实角色

/** * 真实角色 * */public class RealSubject extends Subject{    @Override    public void request() {        System.out.println("From real Subject");    }}

3、代理角色

/** * 代理角色 * */public class ProxySubject extends Subject {    //真实角色的引用    private RealSubject realSubject;    @Override    public void request() {        //在真实角色操作之前的附加操作        preRequest();        if(realSubject == null){            realSubject = new RealSubject();        }        //真实角色的操作        realSubject.request();        //在真实角色之后的附加操作        postRequest();    }    private void postRequest() {        System.out.println("Post Request");    }    private void preRequest() {        System.out.println("Pre Request");    }}

具体的使用如下:

public class Test {    public static void main(String[] args) {        ProxySubject proxySubject = new ProxySubject();        proxySubject.request();    }}

测试结果如下
这里写图片描述
从上面方法中我们可以看到静态代理模式必须将真实角色作为代理对象的属性,在实际使用中,一个真实角色必须对应一个代理角色,如果大量使用会导致产生大量的类,那么动态代理模式的好处就体现出来了

动态代理模式

1、接口

/** * 接口1 * */public interface ByeByeService {    public String sayBye(String name);}
/** * 接口2 * */public interface HelloService {    public String SayHello(String name);}

2、真实角色

/** * 真实角色1 * */public class ByeImp implements ByeByeService{    @Override    public String sayBye(String name) {        return "向" + name + "说拜拜了,下次再see啊";    }}
/** * 真实角色2 * */public class HelloImp implements HelloService{    @Override    public String SayHello(String name) {        return "向" + name + "say 你好哦,多多关照哈";    }}

3、通过Proxy的静态方法newProxyInstance

private static Object getInstance(Object obj) {        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new ProxyHandler(obj));    }

4、proxyHandler

public class ProxyHandler implements InvocationHandler{    private Object target;    public ProxyHandler(Object target) {        super();        this.target = target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        Object result = method.invoke(target, args);        System.out.println("返回值 :" + result) ;        return result;    }}

5、测试

public class ProxyTest {    public static void main(String[] args) {        ByeByeService byeByeService = new ByeImp();        ByeByeService byeProxy = (ByeByeService) getInstance(byeByeService);        HelloService helloService = new HelloImp();        HelloService helloProxy = (HelloService) getInstance(helloService);        System.out.println(byeProxy.sayBye("路飞"));        System.out.println(helloProxy.SayHello("娜美"));    }    private static Object getInstance(Object obj) {        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new ProxyHandler(obj));    }}

结果如下!
这里写图片描述
从上面例子可以看出无论有多少个真实角色我们都可以用一个代理完成功能。
好了,代理模式基本over,相信大家结合代码可以非常清晰的理解

0 0
原创粉丝点击