Java代理模式

代理模式

代理模式:指客户端不直接调用目标对象,而是通过调用代理,间接性调用目标对象。
为什么要用代理呢?为一个对象提供一个替身,以控制对这个对象的访问。可以在目标对象基础上,增加额外功能,即扩展目标对象的功能.。

一、静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。
代码示例:
ComputerSell(接口)

/**
 * 接口
 */
public interface ComputerSell {
    void sell();
}

LenovoComputerFactory(目标对象)

/**
 * 联想厂商
 */
public class LenovoComputerFactory implements ComputerSell  {
    @Override
    public void sell() {
        System.out.println("售卖了联想笔记本");
    }
}

LenovoProxcy (代理)

/**
 * 联想电脑代理商
 */
public class LenovoProxcy implements ComputerSell {
    private ComputerSell computerSell;
    //维护目标对象
    public LenovoProxcy(ComputerSell computerSell) {
        this.computerSell=computerSell;
    }
    @Override
    public void sell() {
        System.out.println("执行售卖sell方法前");
        this.computerSell.sell();
        System.out.println("执行售卖sell方法前");
    }
}

测试如下:

/**
 * 测试类
 */
public class MainComputerApp {
    public static void main(String[] args) {
        LenovoComputerFactory lenovoComputerFactory = new LenovoComputerFactory();
        LenovoProxcy lenovoProxcy = new LenovoProxcy(lenovoComputerFactory);
        lenovoProxcy.sell();
    }
}

总结:静态代理可以在不修改目标对象功能的同时,额外扩展功能。然而代理类和目标类都必须实现同一接口,目标类多、代理类多,如果修改接口难以维护。动态代理可以避免这一缺点。

一、动态代理

动态代理基于JDK的API,也叫JDK代理,动态在内存中构建代理对象。这里我们需要目标对象和目标对象实现的接口,然后创建一个动态代理类实现InvocationHandler,重写invoke方法。

代码示例:
接口和目标对象和上面一样

/**
 * 动态代理类
 */
public class MyFactorySellHandler implements InvocationHandler {
    private Object taget = null;
    // 维护目标对象
    public MyFactorySellHandler(Object taget) {
        this.taget = taget;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行售卖sell方法前");
        Object res = method.invoke(taget, args);
        System.out.println("执行售卖sell方法后");
        return res;
    }
}

创建代理对象:
这里需要引用 Proxy.newProxyInstance方法。该方法三个参数分别表示:

  • ClassLoader loader表示目标对象的类加载器
  • Class<?>[] interfaces表示目标对象实现的一组接口
  • InvocationHandler h表示当前的InvocationHandler实现实例对象
/**
 * 测试
 */
public class MainComputerApp {
    public static void main(String[] args) {
        LenovoComputerFactory factory = new LenovoComputerFactory();
        InvocationHandler myFactorySellHandler = new MyFactorySellHandler(factory);
        //代理对象
        ComputerSell obj = (ComputerSell)Proxy.newProxyInstance(factory.getClass().getClassLoader(), 
                factory.getClass().getInterfaces(),
                myFactorySellHandler);
        obj.sell();
    }
}
Java代理模式是一种结构型设计模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。代理对象可以在客户端和目标对象之间充当中介,以便于客户端访问目标对象时,可以在不改变目标对象的情况下添加一些额外的功能,比如安全性、远程访问、缓存等。 在Java中,代理模式可以通过两种方式实现:静态代理和动态代理。静态代理需要手动编写代理类,而动态代理可以在运行时通过反射机制动态生成代理类,更加灵活。 举个例子,假设我们有一个接口`Subject`,其中定义了一些方法。我们希望在调用这些方法时,增加一些额外的日志记录功能。我们可以编写一个代理类`SubjectProxy`,在代理类中实现接口方法并调用目标对象的方法,同时在方法前后添加日志记录的代码。客户端则通过代理类访问目标对象。 静态代理示例代码如下: ```java public interface Subject { void doSomething(); } public class RealSubject implements Subject { @Override public void doSomething() { System.out.println("RealSubject do something."); } } public class SubjectProxy implements Subject { private Subject realSubject; public SubjectProxy(Subject realSubject) { this.realSubject = realSubject; } @Override public void doSomething() { System.out.println("Before do something."); realSubject.doSomething(); System.out.println("After do something."); } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); Subject subjectProxy = new SubjectProxy(realSubject); subjectProxy.doSomething(); } } ``` 动态代理示例代码如下: ```java public class SubjectHandler implements InvocationHandler { private Object target; public SubjectHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before " + method.getName()); Object result = method.invoke(target, args); System.out.println("After " + method.getName()); return result; } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); InvocationHandler handler = new SubjectHandler(realSubject); Subject subjectProxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); subjectProxy.doSomething(); } } ``` 无论是静态代理还是动态代理代理模式都可以在不改变目标对象的情况下,为其添加额外的功能,提高代码的可复用性和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值