设计模式之代理模式
给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy, 它是一种对象结构型模式,代理模式分为静态代理和动态代理。
静态代理
使用场景:当你想对接口中的某个方法添加增强逻辑时可以有俩种选择。一是直接修改原方法,但这样违背了开闭原则“对扩展开放,对修改关闭”。第二种是使用静态代理。所谓静态代理就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前已经确定。静态代理的特点是委托类和代理类实现共同的接口。
举例:有个方法实现了”组团去北京“的逻辑,现在想在旅游完成后添加”拜访亲戚“的逻辑。
创建接口,实现组团去北京方法。
public interface IOrganizedTour { //组团去北京 void travelToBeing(); }
旅行者类,实现接口
public class Traveller implements IOrganizedTour { @Override public void travelToBeing() { System.out.println("旅行社组织3天北京游-包吃包住"); } }
代理类,实现接口及方法增强
public class TravellerProxy implements IOrganizedTour { private Traveller travelCompany; public TravellerProxy(Traveller travelCompany) { this.travelCompany = travelCompany; } @Override public void travelToBeing() { travelCompany.travelToBeing(); visitRelatives(); } private void visitRelatives() { System.out.println("旅游后走访亲戚"); } }
调用测试类输出
public class MainTest { public static void main(String[] args) { Traveller travelCompany = new Traveller(); TravellerProxy travelProxy = new TravellerProxy(travelCompany); travelProxy.travelToBeing(); } }
旅行社组织3天北京游-包吃包住
三天后拜访亲戚
动态代理
举例:
创建一个Person接口
public interface Person { void doSomething(); }
创建一个实现类
public class Bob implements Person { public void doSomething() { System.out.println("Bob doing something!"); } }
创建JDK动态代理类,使其实现InvocationHandler接口。拥有一个名为target的变量,并创建getTarget获取代理对象方法。
/** * JDK动态代理 * 需要实现InvocationHandler接口 */ public class JDKDynamicProxy implements InvocationHandler { //被代理的对象 Person target; // JDKDynamicProxy构造函数 public JDKDynamicProxy(Person person) { this.target = person; } // 获取代理对象 public Person getTarget() { return (Person)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } // 动态代理invoke方法 public Person invoke(Object proxy, Method method, Object[] args) throws Throwable { // 被代理方法前执行 System.out.println("JDKDynamicProxy do something before!"); // 执行被代理的方法 Person result = (Person) method.invoke(target, args); // 被代理方法后执行 System.out.println("JDKDynamicProxy do something after!"); return result; } }
JDK动态代理测试类
public class JDKDynamicTest { public static void main(String[] args) { System.out.println("不使用代理类, 调用doSomething方法"); Person person = new Bob(); person.doSomething(); System.out.println("-------------------------------------- 分割线 --------------------------------------"); System.out.println("使用动态代理类, 调用doSomething方法"); //获取代理类 Person proxyPerson = new JDKDynamicProxy(new Bob()).getTarget(); // 调用doSomething方法 proxyPerson.doSomething(); } }
浙公网安备 33010602011771号