`
linpyi
  • 浏览: 63064 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

代理模式(Proxy)

阅读更多

代理模式分为2种

 

其实就是实现一个代理类,来代理你所需要代理的类,访问的时候,通过访问代理类,来达到一定的效果

 

举个例子:

 

权限:有一个系统有很多权限,比如说只有管理员有增加的功能.用户访问到DAO的saveMessage方法

 

这个其实就是真正需要的保存方法,但是只有管理员才有权限

 

public class DbMessage implements Message{
...

public void saveMessage(String name) throws ForumAlreadyExistsException {

  this.name = name;
  //这里真正将新名称保存到数据库中 
  saveToDb();

}



}

 

怎么办了,创建一个代理类

public class MessageProxy implements Message{

private DbMessage dbMessage; 
private UserBean user;

public ForumProxy(DbMessage dbMessage, UserBean user)
{
this.dbMessage= dbMessage;
this.user= user;
}

.....

public void saveMessage(String name) throws Exception
{
  //只有是系统或论坛管理者才可以修改名称
  if (user.getRight.equal("***")) {
    forum.saveMessage(name);
  }
  else {
    throw new Exception();
  }
}


}

 利用代理类来实现权限的判断,Jive论坛系统的权限好象采用的代理模式,不过如果不是很了解的人,用起来可能会为了使用

 

代理模式而写代理模式,这样就违背了原来的意愿,只有写了一定多的代码的人才能炉火纯青的写.我只能表面理解.

 

1:静态代理.静态代理代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。

 

上面的权限采用的也是静态代理

 

贴一些网上面比较有说明性的代码

 

Subject.java

 

/**
 * 抽象角色
 */
public abstract class Subject {
    abstract public void request();
}

 

RealSubject.java

 

/**
 * 真实角色:实现了Subject的request()方法
 */
public class RealSubject extends Subject {

    public RealSubject() {
    }

    public void request() {
        System.out.println("真实角色的请求方法RealSubject.request()被调用!");
    }
}

 

ProxySubject.java

 

/**
 * 代理角色
 */
public class ProxySubject extends Subject {
    private RealSubject realSubject; // 以真实角色作为代理角色的属性

    public ProxySubject() {
    }

    // 该方法封装了真实对象的request方法
    public void request() {
        preRequest();               //代理前执行的操作
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();     // 此处执行真实对象的request方法
        postRequest();              //代理后执行的操作
    }

    private void preRequest() {
        // something you want to do before requesting
        System.out.println("代理前执行的操作ProxySubject.preRequest()!");
    }

    private void postRequest() {
        // something you want to do after requesting
        System.out.println("代理后执行的操作ProxySubject.postRequest()!");
    }
}

 

Client.java

 

/**
 * 客户端调用
 */
public class Client {
    public static void main(String[] args) {
        Subject sub = new ProxySubject();
        sub.request();
    }
}

 

这就是静态代理,通过访问代理类,来实现想要的方法,

 

客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理 RealSubject类,同样达

 

到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。

 
另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是
实际使用时,一个真实角色必须对应一个 代理角色,如果大量使用会导致类的急剧膨胀.

 

2:动态代理

 

如果事先并不知道真实角色,该如何使用代理,这就是动态代理所要解决的问题.

 

以下引用

 

Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
 
(1)Interface InvocationHandler:该接口中仅定义了一个方法
public object invoke(Object obj,Method method, Object[] args)
在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数
数组。 这个抽象方法在代理类中动态实现。
 
(2)Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容
动态代理类
protected Proxy(InvocationHandler h):构造函数,用于给内部的h赋值。
 
static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载
器,interfaces是真实类所拥有的全部接口的数组。
 
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理
类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)
动态代理类
 
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该
class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然,这个
Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接
管实际的工作
 
在使用动态代理类时,我们必须实现InvocationHandler接口。

 

底下的例子和上面共用同个subject接口,

 

动态代理类DynamicSubject.java

/**
 * 代理处理器
 *
 * 该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;
 * 此外,在该类还实现了invoke方法,该方法中的 method.invoke(sub,args);
 * 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,
 * args为执行被代理对象相应操作所需的参数。
 * 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
 */

public class DynamicSubject implements InvocationHandler {
    private Object sub;       //被代理对象

    public DynamicSubject() {
    }

    /**
     * 构造方法,并初始化被代理对象
     * @param obj 是被代理的对象
     */
    public DynamicSubject(Object obj) {
        sub = obj;
    }

    /**
     *
     * @param proxy  指代理类
     * @param method 被代理的方法
     * @param args   被代理的方法所需要的参数数组
     * @return  在代理实例上处理方法调用并返回结果。
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理前执行的操作!");
        method.invoke(sub, args);
        System.out.println("代理后执行的操作!");
        return null;
    }

 

client.java

/**
 * 客户端
 */
public class Client {
    static public void main(String[] args) throws Throwable {

        RealSubject rs = new RealSubject();     // 在这里指定被代理类
        //通过被代理类对象声明一个代理类对象
        InvocationHandler dynamicSubject = new DynamicSubject(rs);
        Class<?> cls = rs.getClass();

        // 以下是一次性生成代理类实例:
        // 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
        Subject subject = (Subject) Proxy.newProxyInstance(
                cls.getClassLoader(),           //定义代理类的类加载器
                cls.getInterfaces(),            //代理类要实现的接口列表
                dynamicSubject);                //指派方法调用的调用处理程序:InvocationHandler对象

        subject.request();      //调用代理处理器上的方法
    }
}

 

上面用动态代理来代理了静态代理,在运行时生成Class,在生成时候给他一组接口,然后这个class就宣称实现了这些接口

 

上面的例子实现代理了自己写的类,其实动态代理可以代理已有的类,例如vector

 

public class VectorProxy implements InvocationHandler {
    private Object proxyobj;

    public VectorProxy(Object obj) {
        proxyobj = obj;
    }

    public static Object factory(Object obj) {
        Class<?> cls = obj.getClass();

        return Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(), new VectorProxy(obj));
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("before calling " + method);

        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i] + "");
            }
        }
        Object object = method.invoke(proxyobj, args);

        System.out.println("after calling " + method);
        return object;
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        List<String> v = (List<String>) factory(new Vector<String>(10));

        v.add("New");
        v.add("York");
        System.out.println(v);

        v.remove(0);
        System.out.println(v);
    }
}

 

当做个笔记,

分享到:
评论

相关推荐

    代理模式 Proxy Pattern

    ### 代理模式 Proxy Pattern #### 概念定义 代理模式是一种结构型设计模式,它允许程序员为某对象创建一个代理对象来控制对该对象的访问。简单来说,就是在不修改原始类的基础上,通过引入代理对象来扩展类的行为...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    apache开源项目源码commons-proxy-1.0-src(全部高质量代理模式proxy的java源程序)

    全部高质量代理模式proxy的java源程序 java.proxy,代理模式源码,设计模式,apache开源项目源码commons-proxy-1.0-src 各种代理模式操作的工具类源码以及代理模式案例源码,你会从中得到意想不到的效果! apache...

    设计模式之代理模式proxy.zip

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色。代理模式允许我们为一个对象创建一个代理,这个代理对象在客户端和目标对象之间起到中介的作用,可以增强或控制对目标对象的访问。代理模式的主要...

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

    代理模式 proxy-learn.rar

    在`proxy-learn`这个压缩包中,应该包含了这两种代理模式的详细示例代码,供初学者参考学习。对于初学者来说,理解并掌握代理模式是提升编程能力的重要步骤,它能帮助我们更好地理解和应用面向对象设计原则。

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    c++-设计模式之代理模式(Proxy)

    代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...

    结构型模式之代理模式(Proxy)

    代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...

    Android设计模式之代理模式(Proxy Pattern)

    代理模式是设计模式的一种,它的主要目的是在不改变原有对象的基础上,为一个对象提供额外的功能或者控制对这个对象的访问。在Android开发中,代理模式的应用尤为常见,尤其在处理复杂的业务逻辑、网络请求、界面...

    java 设计模式之代理模式(Proxy Pattern)实现代码及设计详解:动态代理模式、静态代理模式

    在这些模式中,代理模式(Proxy Pattern)是一种常用的结构型设计模式,它允许我们为一个对象创建一个代理,该代理对象在客户端和目标对象之间起到中介的作用,可以增加额外的功能或控制访问。 代理模式分为两种...

    Android设计模式之代理模式Proxy浅显易懂的详细说明

    代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    2、代理模式PROXY PATTERN 3、单例模式SINGLETON PATTERN 4、多例模式MULTITION PATTERN 5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT FACTORY PATTERN 7、门面模式FACADE PATTERN 8、适配器...

    代理模式java代码 Proxy(4)

    代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用,可以实现额外的功能,比如监控、权限控制、事务管理等,而客户端无需关心这些细节。...

    Proxy代理模式经典实例(绝对OOP)

    Proxy代理模式是面向对象设计模式中的重要组成部分,它在软件工程中扮演着关键角色,尤其在Java编程中。代理模式的主要目的是为一个对象提供一个替身或者占位符,以便控制对这个对象的访问。这种设计模式允许我们...

    面向对象初学者必须掌握的几种设计模式

    观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是...Strategy:java.util.Comparator就用到了它 代理模式 Proxy:学习Spring IoC容器必须掌握的模式 &lt;br&gt;

    proxy.rar java三种代理模式源码

    这个"proxy.rar"压缩包中包含了这三种代理模式的源代码示例,以及对泛型的应用。 1. 静态代理: 静态代理是最基础的代理形式,它通过创建一个代理类来实现目标接口,并在代理类中调用目标对象的方法。这种方式需要...

    代理模式小例子

    在代理模式中,有三个关键角色:真实目标(Real Subject)、代理(Proxy)和客户端(Client)。真实目标是代理所代表的对象,它执行实际的工作。代理则扮演真实目标的替身,它持有对真实目标的引用,并且在客户端与...

    代理模式(Proxy Pattern)完整示例代码

    代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象可以在原对象进行某些操作之前或之后添加额外的功能。代理模式的核心在于,它提供了一种方式来间接访问或控制目标对象,增加了系统的...

Global site tag (gtag.js) - Google Analytics