[微商代理模式]使用代理模式模拟ORM实体的延时加载

发布时间:2008-11-26   来源:java    点击:   
字号:

【www.quanqiunao.cn--java】

.NET中的Entity Framework 和 java里面的 Hibernate都是ORM框架,它们中间都用到延时加载,延时加载对于提高性能,减小服务器内存压力有很大的作用。所谓延时加载,就是只有在第一次调用某个实体的方法或属性时才初始化该实体。延时加载适用于创建开销大的对象。如下,我采用代理模式模拟了一个简单的延时加载的例子。

首先,我定义了一个接口,名为IOperation,定义如下:

 1 public interface IOperation
 2 {
 3     /// <summary>
 4     /// 声明一个描述类信息的方法,由子类实现。
 5     /// </summary>
 6     void Describe();
 7     /// <summary>
 8     /// 声明一个销毁订单的操作,由子类操作
 9     /// </summary>
10     void DestoryOrder();
11 }

     然后定义两个实体类,Product类和Order类,分别表示两个相互关联的实体,在Product类中注入Order类的变量用以在Product类中调用Order类的实例方法。并且让Product类实现IOperate接口。

Product类定义如下:

 1 public class Product : IOperation
 2 {
 3     private Order _order;
 4     public Product()
 5     {
 6         Console.WriteLine(">>开始初始化Product类...");
 7         Stopwatch sw = new Stopwatch();
 8         sw.Start();
 9         this._order = new Order();
10         sw.Stop();
11         Console.WriteLine(">>初始化Product类完成。耗时:{0}秒", sw.ElapsedMilliseconds / 1000);
12     }
13     public void Describe()
14     {
15         Console.WriteLine(">>Product描述:我的是Product类的实例,Describe方法执行完成。");
16     }
17     public void DestoryOrder()
18     {
19         Console.WriteLine(">>Product.DestoryOrder()方法开始执行...");
20         if (_order != null)
21         {
22             //调用Order类的Destroy实例方法,销毁自己。
23             _order.Destroy();
24             Console.WriteLine(">>Product.DestoryOrder()方法执行完成。");
25         }
26     }
27 }

Order类定义如下: 

 1 public class Order
 2 {
 3     public Order()
 4     {
 5         Console.WriteLine(">>开始初始化Order类...");
 6         System.Threading.Thread.Sleep(5000);
 7         Console.WriteLine(">>初始化Order类完成。");
 8     }
 9 
10     public void Destroy()
11     {
12         Console.WriteLine(">> Order 已销毁。");
13     }
14 }

然后在主程序里面调用一下:

 1 static void Main(string[] args)
 2 {
 3     Console.WriteLine("==========不使用代理类调用Describe()方法===============");
 4     Product p = new Product();
 5     p.Describe();
 6     Console.WriteLine("==========不使用代理类调用DestoryOrder()方法===============");
 7     Product p2 = new Product();
 8     p2.DestoryOrder();
 9     Console.ReadKey();
10 }

测试结果如下:

      从上图中,我们可以看出,调用Describe()方法初始化Product类用了5秒,这是不是有问题?再看看上面的Describe()方法的实现,只简单的输出了一句话,怎么会用5秒?再看Product的构造函数里面,在初始化Product类的实例的时候,把Order类也初始化了,但是我这个Describe()方法并没有调用Order类的任何方法和属性,所以这就造成了不必要的内存开销,而且初始化了的Order类的实例也没有使用,产生了垃圾对象。

      怎么解决这个问题呢?所以这个地方就得用代理了,代理是个什么东西呢?代理简单来说,就是制造一个与被调对象具有相同功能(这个相同功能通常由接口去规范)的类,在这个类中可以调用被调对象的方法,也可以自定义新的方法供调用方使用。下面就是代理类的创建。

首先,我创建一个代理类,名为ProxyProduct,让它也实现IOperate接口,定义如下:

 1public class ProxyProduct : IOperation
 2{
 3    private IOperation entity;
 4
 5    public ProxyProduct(IOperation entity)
 6    {
 7        Console.WriteLine(">>开始初始化ProxyProduct...");
 8        Stopwatch sw = new Stopwatch();
 9        sw.Start();
10        this.entity = entity;
11        sw.Stop();
12        Console.WriteLine(">>初始化ProxyProduct完成。耗时:{0}秒", sw.ElapsedMilliseconds / 1000);
13    }
14    /// <summary>
15    /// 实现IOperation的方法
16    /// </summary>
17    public void Describe()
18    {
19        Console.WriteLine(">>ProxyProduct描述:我的是ProxyProduct类的实例,Describe()方法执行完成。");
20    }
21    /// <summary>
22    /// 实现IOperation的方法
23    /// </summary>
24    public void DestoryOrder()
25    {
26        Console.WriteLine(">>ProxyProduct.DestoryOrder()方法开始执行...");
27        if (entity == null)
28        {
29            entity = new Product();
30        }
31        entity.DestoryOrder();
32        Console.WriteLine(">>ProxyProduct.DestoryOrder()方法执行完成。");
33    }
34}

在主程序里面测试一下:

 1 static void Main(string[] args)
 2 {
 3     Console.WriteLine("==========使用代理类调用Describe()方法===============");
 4     IOperation desc = new ProxyProduct(null) as IOperation;
 5     if (desc != null)
 6     {
 7         desc.Describe();
 8     }
 9     Console.WriteLine("==========使用代理类调用DestoryOrder()方法===============");
10     IOperation desc2 = new ProxyProduct(null) as IOperation;
11     if (desc2 != null)
12     {
13         desc2.DestoryOrder();
14     }
15     Console.ReadKey();
16 }

测试结果如下:

i)))))
&7:^Cۜ޲zCz+gngngngngn۲kyjava代码实现:
接口:IOperate

 1 public interface IOperate {
 2     /**
 3      * 声明一个描述类信息的方法,由子类实现。
 4      */
 5     void describe();
 6     /**
 7      * 声明一个销毁订单的方法,由子类实现。
 8      */
 9     void destroyOrder();
10 }


实现类:ProductBean

 1 public class ProductBean implements IOperate {
 2     private OrdersBean ordersBean;
 3 
 4     /**
 5      * 初始化ProductBean类的实例
 6      */
 7     public ProductBean() {
 8         System.out.println(">>开始初始化ProductBean....");
 9         long startTime = System.currentTimeMillis();
10         this.ordersBean = new OrdersBean();
11         long endTime = System.currentTimeMillis();
12         System.out.println(">>初始化ProductBean完成。耗时:" + (endTime - startTime) / 1000 + "秒");
13     }
14 
15     public void describe() {
16         System.out.println(">>describe描述:我是ProductBean类,执行了describe()方法。");
17     }
18 
19     public void destroyOrder() {
20         System.out.println(">>开始执行ProductBean.destroyOrder()方法...");
21         if (this.ordersBean != null) {
22             this.ordersBean.destroy();
23             System.out.println(">>ProductBean.destroyOrder()方法执行完成。");
24         }
25     }
26 }

实体类:OrderBean

 1 public class OrdersBean {
 2     public OrdersBean() {
 3         System.out.println(">>开始初始化OrderBean.....");
 4         InitOrder();
 5         System.out.println(">>初始化OrderBean完成。");
 6     }
 7 
 8     /**
 9      * 初始化订单
10      */
11     private void InitOrder() {
12         try {
13             // 加载订单数据,这里模拟耗时3秒。
14             Thread.sleep(5000);
15         } catch (Exception e) {
16             e.printStackTrace();
17         }
18     }
19     
20     public void destroy() {
21         System.out.println(">> Order 已销毁。");
22     }
23 }

代理类:ProxyProductBean

 1 public class ProxyProductBean implements IOperate {
 2     private IOperate bean;
 3 
 4     public ProxyProductBean(IOperate bean) {
 5         System.out.println(">>开始初始化ProxyProductBean.....");
 6         long startTime = System.currentTimeMillis();
 7         this.bean = bean;
 8         long endTime = System.currentTimeMillis();
 9         System.out.println(">>初始化ProxyProductBean完成。耗时:" + (endTime - startTime) / 1000 + "秒");
10     }
11 
12     public void describe() {
13         System.out.println(">>describe描述:我是ProxyProductBean类,执行了describe()方法。");
14     }
15 
16     public void destroyOrder() {
17         System.out.println(">>开始执行ProxyProductBean.destroyOrder()方法...");
18         if (bean == null) {
19             bean = new ProductBean();
20             bean.destroyOrder();
21             System.out.println(">>执行ProxyProductBean.destroyOrder()方法完成。");
22         }
23     }
24 }

测试类:

 1 public class Test {
 2     public static void main(String[] args) {
 3         System.out.println("==========不使用代理类调用describe()方法===============");
 4         ProductBean productBean = new ProductBean();
 5         productBean.describe();
 6         System.out.println("==========使用代理类调用describe()方法===============");
 7         IOperate description = (IOperate) (new ProxyProductBean(null));
 8         description.describe();
 9         System.out.println("==========不使用代理类调用cascadeOperate()方法===============");
10         ProductBean productBean2 = new ProductBean();
11         productBean2.destroyOrder();
12         System.out.println("==========使用代理类调用cascadeOperate()方法===============");
13         IOperate description2 = (IOperate) (new ProxyProductBean(null));
14         description2.destroyOrder();
15     }
16 }


测试结果输出如下:
==========不使用代理类调用describe()方法===============
>>开始初始化ProductBean....
>>开始初始化OrderBean.....
>>初始化OrderBean完成。
>>初始化ProductBean完成。耗时:5秒
>>describe描述:我是ProductBean类,执行了describe()方法。
==========使用代理类调用describe()方法===============
>>开始初始化ProxyProductBean.....
>>初始化ProxyProductBean完成。耗时:0秒
>>describe描述:我是ProxyProductBean类,执行了describe()方法。
==========不使用代理类调用cascadeOperate()方法===============
>>开始初始化ProductBean....
>>开始初始化OrderBean.....
>>初始化OrderBean完成。
>>初始化ProductBean完成。耗时:5秒
>>开始执行ProductBean.destroyOrder()方法...
>> Order 已销毁。
>>ProductBean.destroyOrder()方法执行完成。
==========使用代理类调用cascadeOperate()方法===============
>>开始初始化ProxyProductBean.....
>>初始化ProxyProductBean完成。耗时:0秒
>>开始执行ProxyProductBean.destroyOrder()方法...
>>开始初始化ProductBean....
>>开始初始化OrderBean.....

本文来源:http://www.quanqiunao.cn/bianchengkaifa/7909/