现在的位置: 首页 > 综合 > 正文

java设计模式(4)–代理模式

2013年01月06日 ⁄ 综合 ⁄ 共 2081字 ⁄ 字号 评论关闭

一、静态代理类:

由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

该模式有以下角色:

(1)抽象角色(Subject):负责声明真实对象和代理对象的共同接口;

(2)代理角色(ProxySubject):内部包含真实对象的引用,负责对真实对象进行再封装以提供特定的服务。

(3)真实角色(RealSubject):被代理的真实对象,负责提供实现的具体服务。

/**
 * 抽象角色
 */
public interface Subject {
	public void say();
}

/**
 * 真实角色
 *
 */
public class RealSubject implements Subject {

    @Override
    public void say() {
        System.out.println("hello world!");

    }
}

/**
 * 代理角色
 */
public class ProxySubject implements Subject{
    
    //真实角色引用
    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }
    
    @Override
    //对真实对象进行再封装,并在真实对象的前后进行切面处理
    public void say() {
        System.out.println("start saying...");
        //相当于回调
        subject.say();
        System.out.println("stop saying...");    
    }
}
/**
 * 测试类
 */
@Test
public void test2()
{
     Subject s = new RealSubject();

     ProxySubject ps = new ProxySubject(s);

     ps.say();
}

缺点:(1)当我们在抽象对象中增加一个方法时,那么不仅在真实角色中需要进行修改,代理角色中也要进行修改。

(2)每个代理类只能为一个抽象角色服务(如果我们一个代理类实现多个接口,那么一个代理就可以用到所有的接口的方法而非自己接口的方法),这样会产生过多的同功能代理类,而且各代理类除了调用的方法不一样之外,其它代码都一样,代码重复严重。

二、动态代理类

在程序运行时,运用反射机制动态创建而成。

JDK提供了java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类支持动态代理的实现。

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。

/**
 * 抽象角色(同静态代理)
 */
public interface Subject {
	public void say();
}

/**
 * 真实角色(同静态代理)
 *
 */
public class RealSubject implements Subject {

    @Override
    public void say() {
        System.out.println("hello world!");

    }
}


/**
 * 动态代理类
 *
 */
//继承自java.lang.reflect.InvocationHandler接口
public class DynamicProxy implements InvocationHandler{
    
    //真实对象引用
    private Object subject;
    
    public DynamicProxy(Object subject) {
        super();
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
        System.out.println("welcome ");
        Object result = method.invoke(subject, args);
        return result;
    }
}

/**
 * 测试类
 */
@Test
public void test4(){   
    Subject  s = new RealSubject();    
    DynamicProxy dp = new DynamicProxy(s);    
    Subject sProxy = (Subject)Proxy.newProxyInstance(s.getClass().getClassLoader(), new Class[]{Subject.class},dp);    
    sProxy.say();
}

缺点:(1)只能代理实现了接口的类,有些类没实现接口的就不能使用JDK代理。

三、应用场合

         (1)不允许直接访问某些类;

         (2)对访问要做特殊处理等



抱歉!评论已关闭.