设计模式四—"代理模式"(静态代理)

代理模式的一个核心思想就是通过实现延迟加载,提升系统启动速度,提升用户体验。当然代理模式还有其他的优势,比如安全考虑,或者远程调用等等。同时,Java的动态代理技术也具有很高的灵活性。

从静态代理开始

先从一个实际情况下可能碰到的例子来说明代理模式。

代理模式主要有三个主要组成

(1)代理类与真实主题公共提供对外的主题接口

(2)代理类,用来代理或封装真实主题

(3)真实主题,封装真正的业务逻辑

Example:

(1)主题接口,定义一个DBQuery接口

1 package com.sample;
2 
3 public interface IDBQuery {
4     public String query();
5     public void insert();
6     public void update();
7     public void delete();
8 }

(2)真实主题类,实现真正request业务逻辑测试代码中用一个Tread.sleap()来模拟这类真实封装了业务逻辑的类的实例化操作。

 1 package com.sample;
 2 
 3 public class DBQuery implements IDBQuery {
 4     public DBQuery(){
 5         try{
 6             Thread.sleep(10000);//simulate ops creating connections between
 7         }
 8         catch(Exception ie){
 9             ie.printStackTrace();
10         }
11     }
12     
13     public String query() {
14         return "request str";
15     }
16         public void update() {
17         System.out.println("update a record");
18     }
19 
20     public void insert() {
21         System.out.println("insert a record");
22     }
23 
24     public void delete() {
25         System.out.println("delete a record");
26     }
27 }

(3)代理类,实现延迟加载,轻量级对象,创建非常快

 1 package com.sample;
 2 
 3 public class DBQueryProxy implements IDBQuery{
 4     private IDBQuery instance = null;
 5     
 6     public DBQueryProxy(){
 7     }
 8     public DBQueryProxy(IDBQuery iDBQuery){
 9         this.instance = iDBQuery;
10     }
11     public String query() {
12         lazyInit();
13         return instance.query();
14     }
15     
16     public void insert() {
17         lazyInit();
18         instance.insert();
19     }
20 
21     public void update() {
22         lazyInit();
23         instance.update();
24     }
25 
26     public void delete() {
27         lazyInit();
28         instance.delete();
29     }
30     
31     public void lazyInit(){
32         if(instance == null)
33             instance = new DBQuery();
34     }
35 }

测试使用代理类

 1 package com.sample;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         IDBQuery dbQueryProxy = new DBQueryProxy();
 6         long begTime = System.currentTimeMillis();
 7         System.out.println(dbQueryProxy.query());
 8         long endTime = System.currentTimeMillis();
 9         System.out.println("Proxy init real Subject cost:" + (endTime-begTime));
10         dbQueryProxy.update();
11         dbQueryProxy.insert();
12         dbQueryProxy.delete();
13     }
14 }

只用当dbQuery调用query的时候,封装了业务逻辑的类才会被实例化。使用代理模式的目的在于加速系统启动时间,有点类似于hibernate的lazy init。

同时使用代理类,隐藏了真实主题内的业务逻辑,在安全性方面的优势也就体现了出来。

来段总结吧:我们可以这样理解代理模式带来的性能优势,用户需要请求一个db的connection,而创建connection是一个非常耗时的操作,如果请求了,就去实例化对象,执行业务逻辑,如果没有请求的话,不会实例化对象,这样在服务端的性能优势就体现出来了。

但是静态代理也有缺点,假设主题接口中提供较多的方法,为每一个接口都去写一个代理方法非常麻烦,如果接口产生变化,封装了业务逻辑的真实主题类,和代理类中的代理方法的实现代码就需要大量的修改工作。java中的动态代理技术就能很好的处理这个问题。使用动态代理技术,不需要再为真是主题写一个形式上完全一样的代理类,同时,我们可以在程序中动态指定代理类的执行逻辑,灵活性非常大~

 

 

posted @ 2013-05-22 16:21  RichardHu  阅读(144)  评论(0编辑  收藏  举报