代理模式

1.1 静态代理
• 抽象角色:一般会使用接口或者抽象来解决
• 真实角色:被代理的角色
• 代理角色: 代理真实角色,代理真实角色后,我们一般会做一些附属操作
• 客户:访问代理的人!
真实类:
//房东 public class Host implements Rent { public void rent() { System.out.println("房东要组房"); } }
抽象角色:接口
//租房 public interface Rent { public void rent(); }
代理角色:
//中介 public class Proxy implements Rent{ private Host host; public Proxy(Host host) { this.host = host; } public Proxy() { } public void rent() { seeHouse(); host.rent(); free(); } //看房 public void seeHouse(){ System.out.println("中介看房"); } //收中介费 public void free(){ System.out.println("中介收中介费"); } }
客户:
public class Client { public static void main(String[] args) { Host host =new Host(); //代理 中介帮房东看房子 Proxy proxy = new Proxy(host); //不用找房东 直接找中介 直接接触中介 proxy.rent(); } }
租客租房不用面对房东,直接找中介租房即可!
代理模式的好处:
• 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
• 公共业务交给代理角色!实现了业务的分工!
• 公共业务发生扩展的时候,方便集中管理!
缺点:
• 一个则真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。
使用静态代理加入日志
真实类:
//真实对象 public class UserServiceImpl implements UserService{ public void add() { System.out.println("增加一个用户"); } public void delete() { System.out.println("删除一个用户"); } public void update() { System.out.println("修改一个用户"); } public void find() { System.out.println("查找一个用户"); } }
抽象角色:
//抽象角色 public interface UserService { public void add(); public void delete(); public void update(); public void find(); }
代理对象
//代理对象 public class UserServiceProxy implements UserService { private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } public void add() { log("add"); userService.add(); } public void delete() { log("delete"); userService.delete(); } public void update() { log("update"); userService.update(); } public void find() { log("find"); userService.find(); } //加入日志功能,在实现真实类的操作前,记录日志 public void log(String msg){ System.out.println("使用了"+msg+"方法"); } }
客户
public class Client { public static void main(String[] args) { UserServiceImpl impl=new UserServiceImpl(); UserServiceProxy proxy=new UserServiceProxy(); proxy.setUserService(impl); proxy.add(); } }
1.2 动态代理
使用动态代理租房:
真实类:
//房东 public class Host implements Rent { public void rent() { System.out.println("房东要组房"); } }
抽象角色:
//租房 public interface Rent { public void rent(); }
代理角色:
//会用这个类自动生成代理 public class ProxyInvocationHandler implements InvocationHandler { private Rent rent; public void setRent(Rent rent){ this.rent=rent; } //生成代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } //处理代理实例 ,返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); ///c处理动态类的本质,就是反射机制 Object result = method.invoke(rent, args); free(); return result; } public void seeHouse(){ System.out.println("中介看房子"); } public void free(){ System.out.println("中介收费"); } }
客户:
public class Client { public static void main(String[] args) { //真实角色 Host host=new Host(); //代理教角色,现在没有 ProxyInvocationHandler proxyInvocationHandler=new ProxyInvocationHandler(); //通过调用程序处理角色来处理我们要调用的接口对象 proxyInvocationHandler.setRent(host); //这里的proxy就是动态生成的,我们并没有写 Rent proxy =(Rent) proxyInvocationHandler.getProxy(); proxy.rent(); } }
使用动态代理生成日志:
代理对象: 可当作模板
//会用这个类自动生成代理 public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target){ this.target=target; } //生成代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //处理代理实例 ,返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); ///c处理动态类的本质,就是反射机制 Object result = method.invoke(target, args); return result; } public void log(String msg){ System.out.println("执行力"+msg+"方法"); } }
客户:
public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService =new UserServiceImpl(); //代理角色 不存在 ProxyInvocationHandler pih= new ProxyInvocationHandler(); //设置要代理的对象 pih.setTarget(userService); //动态生成代理类 UserService proxy=(UserService) pih.getProxy(); proxy.add(); } }
动态代理的好处:
• 可以使用真实角色的操作更加纯粹! 不用去关注一些的公共业务
• 公共业务就交给代理角色! 实现了业务的分工!
• 公共业务发生扩展的时候,方便集中管理!
• 一个动态代理类代理的是一个接口,一般就是对应的一类业务
• 一个动态代理可以代理多个类,只要是实现了同一个接口即可!


浙公网安备 33010602011771号