代理模式
使用代理模式可以在不改变原有对象的基础上对该对象的某些行为进行增强。
现实生活中有许多例子,比如说代理商,厂家批发给代理商,代理商负责给厂家销售,代理商作为中介完成了消费者和厂家进行交互的行为。
静态代理
UML类图如下所示:
说明:Producer是衣服厂家和衣服专卖店的一个抽象,ClothesProducer具有的行为ClothesShop通过实现Producer接口都有,ClothesShop通过持有一个成员producer完成ClothesProducer的原始操作。
Java代码如下所示:
package proxy; public interface Producer { public void sale(); } package proxy; public class ClothesProducer implements Producer { private String brand; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } @Override public void sale() { System.out.println(brand); } } package proxy; public class ClothesShop implements Producer { // 卖谁的衣服 private Producer producer; public ClothesShop(Producer producer) { this.producer = producer; } @Override public void sale() { // 开始吆喝 System.out.println("我们卖的是 "); producer.sale(); System.out.println("牌服装!"); } } package proxy; public class Client { public static void main(String[] args) { // 实际的对象 ClothesProducer clothesProducer = new ClothesProducer(); clothesProducer.setBrand("耐克"); // 代理的对象 Producer clothesShop = new ClothesShop(clothesProducer);// 将实际对象塞进去 // 完成销售 clothesShop.sale(); } }
消费者直接通过专卖店的代理直接买到了衣服,再也不用去联系厂家了,多方便呀!
JDK动态代理
- 使用静态代理的好处显而易见,我们能方便地看到代理类的代码(这是我们自己写的),但是如果需要代理的对象很多,为所属不同类的多个实际对象书写代理类是件费力不讨好的事情,因此使用JDK动态代理就会便利很多。
后来这家厂商做牛逼了,觉得给专卖店太坑,自己来,怎么做呢?我请一个代理不就解决了。
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ClothesProducer implements Producer,InvocationHandler { private Producer proxy; private String brand; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } @Override public void sale() { System.out.println(brand); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我们卖的是 "); Object result = method.invoke(this, args); System.out.println("牌服装!"); return result; } // 请的代理,价格比专卖店低很多 public Producer createProxy(Producer producer){ proxy = (Producer) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), this); return proxy; } } package proxy; public class Client { public static void main(String[] args) { // 实际的对象 ClothesProducer clothesProducer = new ClothesProducer(); clothesProducer.setBrand("耐克"); // 代理的对象 Producer proxy = clothesProducer.createProxy(clothesProducer); // 完成销售 proxy.sale(); } }
使用jdk动态代理的优点是我们再也不必去书写大量的代理类以及修改代理类了,因为jdk动态代理的原理就是动态生成class文件来达到静态代理的效果的,所以jdk动态代理的速度会比静态代理低一些,同时代码也没有静态代理代码易于理解。
注意:JDK动态代理只能为有接口实现的类做代理。