代理模式
来源:互联网 发布:淘宝买啥弓箭好 编辑:程序博客网 时间:2024/04/30 22:07
个人笔记,请不要被误导。
代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问。(被代理的对象可以是远程的对象、创建开销大的对象或需要安全控制的对象,下面的三个例子远程代理、虚拟代理和保护代理分别代表这三类)。
实体和代理者实现同一个接口,用户用的时候不用关心究竟是谁,实现用户和实体的解耦。一般代理者都有实体的引用,这样才能调用它。这和适配器模式很相似区别在于前者代理者和实体实现同一个接口。
远程代理:
这里的例子是GumBallMonitor监视GumBallMachine(糖果机)的location、count和State(自己创建的类,表示糖果机状态)。这里用java RMI,它可以帮忙自动创建代理者。需要我们先建立一个远程接口
GumballMachineRemote implements Remote。然后建立远程实体类,它要实现GumballMachineRemote,而且要继承UnicastRemoteObject。这才为GumballMachineRemote接口和远程实体类建立联系,而且能为远程实体类建立代理者,GumballMachineRemote类型的代理者。此外,State类的对象不能被打包,只有序列化的数据类型才可以。所以State类声明时要加上extends Serializable。State类不需要通过网络传来的变量声明为transient。下面要做的就是通过Naming.rebind()方法把远程实体类对象的代理者注册,这里它有一个类似id的东西,以后可以通过Naming.lookUp()方法利用id传回相应远程实体对象的代理者。传回来的代理者类型是远程接口的,这是客户不用关心的。
import java.rmi.Remote;import java.rmi.RemoteException;public interface GumballMachineRemote extends Remote {//考虑是否有风险,所有方法throw RemoteException public int getCount() throws RemoteException; public String getLocation() throws RemoteException; public State getState() throws RemoteException;}
import java.rmi.RemoteException;public class GumballMonitor { GumballMachineRemote gumballMachineRemote; public GumballMonitor(GumballMachineRemote gumballMachineRemote){ this.gumballMachineRemote = gumballMachineRemote; } public void report(){ try { gumballMachineRemote.getCount(); gumballMachineRemote.getLocation(); gumballMachineRemote.getState(); } catch (RemoteException e) { e.printStackTrace(); } }}
虚拟代理:
这里例子是ImageProxy对象代理ImageIcon对象。因为后者创建的开销太大。加载一个很大的图片时不能一直空白,让用户等,要出现一个loading的图片,提示用户在加载。这个展示loading图片的对象,就是代理者——ImageProxy。ImageProxy判断ImageIcon是否加载完来执行相应操作。
public class ImageProxy implements Icon { ImageIcon imageIcon; DocFlavor.URL imageURL; boolean retrieving = false; Thread retrievalThread; public ImageProxy(DocFlavor.URL url){ imageURL = url; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { if (imageIcon != null) imageIcon.paintIcon(c,g,x,y); g.drawString("Loading",x + 300,y + 190); if (!retrieving){ retrieving = true; retrievalThread = new Thread(new Runnable() { @Override public void run() { imageIcon = new ImageIcon(String.valueOf(imageURL),"CD Cover"); c.repaint(); } }); retrievalThread.start(); } } @Override public int getIconWidth() { if (imageIcon == null) return 600; else return imageIcon.getIconWidth(); } @Override public int getIconHeight() { return 0; }}
保护代理:这是一个动态代理,代码执行之前Proxy类(注意是类!不是对象)还没被创建出来。
java.lang.reflect有自己的代理支持。这里的代理者会调用InvocationHandler类的方法,这里的方法判断客户发的需求,选择执行或不执行,达到保护的目的。
案例里有OwnerInvocationHandler和NonOwnerInvocationHandl两个InvocationHandler类,代理者根据发出请求的是自己还是别人(案例里自己不能改自己被点赞的次数,别人不能改自己的信息)调用这两个类,进行不同的操作。
public class OwnerInvocationHandler implements InvocationHandler { PersonBean personBean; public OwnerInvocationHandler(PersonBean personBean){ this.personBean = personBean; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (method.getName().startsWith("get")) return method.invoke(personBean,args); if (method.getName().equals("setHotOrNotRating")) throw new IllegalAccessException(); else if (method.getName().startsWith("set") ) return method.invoke(personBean,args); }catch (InvocationTargetException e){ e.printStackTrace(); } return null; }}
public interface PersonBean { public String getName(); public void setName(String name); public int getHotOrNotRating(); public void setHotOrNotRating(int hotOrNotRating);}
import java.lang.reflect.Proxy;public class PersonBeanImpl implements PersonBean { String name; int hotOrNotRating; @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public int getHotOrNotRating() { return hotOrNotRating; } @Override public void setHotOrNotRating(int hotOrNotRating) { this.hotOrNotRating = hotOrNotRating; } public PersonBean getOwnerProxy(){ return (PersonBean) Proxy.newProxyInstance(this.getClass().getClassLoader(),this.getClass().getInterfaces(),new OwnerInvocationHandler(this)); }}
public void ProxyPattern_Protect(){ PersonBeanImpl personBean = new PersonBeanImpl(); PersonBean ownProxy = personBean.getOwnerProxy(); ownProxy.getHotOrNotRating(); ownProxy.setHotOrNotRating(100); }
- 代理模式--动态代理
- 代理模式-静态代理
- 代理模式-静态代理
- 代理模式 & 动态代理
- 代理模式--静态代理
- 代理模式--动态代理
- 代理模式(动态代理)
- 代理模式-动态代理
- 代理模式-动态代理
- 代理模式动态代理
- 代理模式-静态代理
- 代理模式-动态代理
- 代理模式 -动态代理
- 代理模式---动态代理
- 代理模式-动态代理
- 代理模式--静态代理
- 代理模式!
- 代理模式
- 移动端Web页面适配方案
- 菱形
- 判断拐弯
- 【SSLGZ 2811】2017年10月30日提高组T2 摘Galo
- TSP问题及蚁群算法理解与实现
- 代理模式
- 用SQL profiler工具抓指定表名的动态
- Y
- [Tensor] tf.nn.conv2d函数中的padding参数
- java通过反射实现HttpServlet
- intellij idea编辑器里面的字母有的隐形了是为什么
- 超级楼梯(斐波那契数列应用)
- Ubuntu下使用root账号登录
- maya(学习笔记)之骨骼中关节的轴向确定方法