代理设计模式
- 特点:两个子类共同实现一个接口,其中一个子类负责真实业务实现,另一个子类完成辅助真实业务主题的操作
- 代码:
interface ISubject{ void buyComputer(); }
class RealSubject implements ISubject{ @Override public void buyComputer() { System.out.println("买一台外星人电脑"); } }
class ProxySubject implements ISubject{ private ISubject subject; public ProxySubject(ISubject subject) { this.subject = subject; } public void produceComputer(){ System.out.println("生产外星人电脑"); } public void afterSale(){ System.out.println("外星人电脑售后团队"); } @Override public void buyComputer() { this.produceComputer(); this.subject.buyComputer(); this.afterSale(); } }
class Factory{ public static ISubject getInstance(){ return new ProxySubject(new RealSubject()); } }
public class Test { public static void main(String[] args) { ISubject subject = Factory.getInstance(); subject.buyComputer(); } }
- 本质:所有的真实业务操作都会有一个与之辅助的工具类(功能类)共同完成
动态代理设计模式
特点:
- 在程序运行时,通过反射机制动态生成,动态代理类通常代理接口下的所有类。
- 动态代理事先不知道要代理的是什么,只有在运行的时候才能确定。
- 动态代理的调用处理程序必须先实现InvocationHandler接口,及使用Proxy类中的newProxyInstance方法动态的创建代理类,并覆写invoke方法,用来回调非主营业务。
- Java动态代理只能代理接口,要代理类需要使用第三方的cligb等类库。
代码:
package com.github.Factory; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface ISubject{ void eat(String msg, int num); } class RealSubject implements ISubject{ @Override public void eat(String msg, int num) { System.out.println("我要吃"+num+"个"+msg); } } class ProxySubject implements InvocationHandler{ private Object target; public ProxySubject(Object target) { this.target = target; } public Object ProxyInstance(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } public void preHandle(){ System.out.println("-------------before---------"); } public void aftHandle(){ System.out.println("-------------After-----------"); } @Override public Object invoke(Object proxy, Method method, Object[] args) { preHandle(); Object ret = null; try { ret = method.invoke(this.target,args); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } aftHandle(); return ret; } } public class Client { public static void main(String[] args) { ProxySubject proxySubject = new ProxySubject(new RealSubject()); ISubject iSubject = (ISubject)proxySubject.ProxyInstance(); iSubject.eat("面包",10); } }