设计模式学习笔记—代理模式
来源:互联网 发布:js怎么隐藏一个div 编辑:程序博客网 时间:2024/05/18 18:15
代理模式(Proxy Pattern)
如果想在一个类中大多数方法之前或之后统一做一些事,那就用代理模式吧。
代理模式的用途也不少,比如大多数 service 中的方法之前都要判断一下用户是否登录,如果没有登录肯定就不能让这个用户进行操作,或者 dao 中每次都要打开然后关闭一些东西什么的,这样就可以把这些公共的部分提取出来,比较著名的 spring 面向切面编程(AOP) 就是代理模式的一种实现,虽然我已经忘了 AOP 怎么写的了。 T T
正常情况下的代理模式(所以肯定有非正常的 = =),要与被代理的类继承同一个接口,就像这样
public interface BookService { List<Book> getByUserId(int userId); void create(Book book, int userId); void update(Book book); void delete(Book book);}
public class BookServiceImpl implements BookService { @Override public List<Book> getByUserId(int userId) { System.out.println("get"); return new ArrayList<Book>(); } @Override public void create(Book book, int userId) { System.out.println("create"); } @Override public void update(Book book) { System.out.println("update"); } @Override public void delete(Book book) { System.out.println("delete"); }}
public class ServiceProxy implements BookService { private BookService mBookService; public ServiceProxy(BookService bookService) { mBookService = bookService; } @Override public List<Book> getByUserId(int userId) { this.before(); List<Book> books = mBookService.getByUserId(userId); this.after(); return books; } @Override public void create(Book book, int userId) { this.before(); mBookService.create(book, userId); this.after(); } @Override public void update(Book book) { this.before(); mBookService.update(book); this.after(); } @Override public void delete(Book book) { mBookService.delete(book); } private void before() { System.out.println("before"); } private void after() { System.out.println("after"); }}
然而这些代码并没有什么实际的意义,话说 service 和 dao 的例子我已经用了好多个了,Because I think that the majority of people studied it in college.(然而我英语并不好 - -)
调用的时候会是这样
BookService bookService = new ServiceProxy(new BookServiceImpl()); bookService.create(new Book(), 1); bookService.delete(new Book());
看起来调用还不错,作为一个设计模式而言,不过不单单是这一个类需要这样的代理,可能程序中的每一个 service 都需要一个代理,虽然可以用工厂给封装起来,但是那么多的代理类基本上也是做的相同的工作,所以就有了动态代理。
public class ServiceProxy implements InvocationHandler { private Object mServiceObj = null; public ServiceProxy(Object serviceObj) { mServiceObj = serviceObj; } private void before() { System.out.println("before"); } private void after() { System.out.println("after"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 这就是为什么 service 中经常以这种规范进行命名的原因 String[] limits = new String[] {"get", "create", "update"}; boolean isAllow = false; String methodName = method.getName(); for (String limit : limits) { if (methodName.startsWith(limit)) { isAllow = true; } } Object result = null; if (isAllow) { this.before(); } // 这个就是需要执行的那个方法 result = method.invoke(mServiceObj, args); if (isAllow) { this.after(); } return result; }}
代理类的话改动比较大,实际上就多了几行对于方法名限定,如果简单的话完全可以这么写
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; this.before(); // 这个就是需要执行的那个方法 result = method.invoke(mServiceObj, args); this.after(); return result; }
然后,我们需要一个工厂,不然调用部分的代码会很难看
public class ServiceFactory { public static Object getBean(String name) { if ("bookService".equals(name)) { BookService service = new BookServiceImpl(); ServiceProxy proxy = new ServiceProxy(service); return Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), proxy); } return null; }}
嘛,工厂的责任就是负责组装好组件之间的关系,最后的调用会是这个样子的
BookService bookService = (BookService) ServiceFactory.getBean("bookService"); bookService.create(new Book(), 1); bookService.delete(new Book());
这样看起来就好多了。
PS:如果将代理类作为一个模板方法,before after 之类的延迟到子类去实现,工厂负责读取 xml,反射创建对象,这样的话应该也能有点框架的意思了吧。
The end.
0 0
- 设计模式学习笔记—代理模式
- 设计模式学习笔记之代理模式
- 【设计模式】代理模式学习笔记
- 设计模式学习笔记--代理(Proxy)模式
- 设计模式学习笔记之代理模式
- 设计模式学习笔记--代理模式
- 设计模式学习笔记-代理模式
- 设计模式学习笔记--代理模式
- java设计模式学习笔记--代理模式
- 《学习笔记》设计模式-代理模式
- HeadFirst 设计模式学习笔记12——代理模式
- 设计模式学习笔记——代理模式
- 《Head First 设计模式》学习笔记——代理模式
- 设计模式学习笔记——代理模式
- 设计模式学习笔记——代理模式
- 设计模式学习笔记——代理(Proxy)模式
- 学习笔记——JAVA设计模式<6>代理模式
- 四、代理模式——设计模式学习笔记
- 初识storm
- 关于Jfinal上传多个文件后台获取变量的问题
- GPT分区表详解
- Windows Server 2003开机自动登录
- 不要被谎言蒙住了你的爱国心
- 设计模式学习笔记—代理模式
- 用subString取出字符串中括号中的字符串
- PCH类的使用
- java编码
- 网站图标添加方法
- QT sleep
- 一Java设计模式——需要遵守的六个原则
- iOS中如何优化Cell中图片的下载性能
- Apache HBase 2015年发展回顾与未来展望