西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → 使用代理模式模拟ORM实体的延时加载

使用代理模式模拟ORM实体的延时加载

相关软件相关文章发表评论 来源:海岛孤雁时间:2011/7/31 23:41:20字体大小:A-A+

作者:海岛孤雁点击:26次评论:0次标签: ORM

ORM一键还原系统V4.1.29.1 官方最新版
  • 类型:备份还原大小:8.8M语言:中文 评分:10.0
  • 标签:
立即下载

.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 }

测试结果如下:

      从上图看出,调用Describe()方法时耗时0秒,调用DestoryOrder()方法时,初始化代理类用了0秒,初始化Product类用了5秒,所以执行DestroyOrder()方法一共花费了5秒。这样的结果是令人满意的,使用代理类就实现了“调用谁的方法,就初始化谁;不调用不初始化”的想法。这样的话,如果我永远只调Describe()方法,那么我花费的时间永远是0秒,而不会产生额外的开销,这对性能优化有很大的帮助。

      总结:代理模式应用之一:对于某些创建时需要很大开销的对象,我们可以使用代理让这个对象在第一次调用它的方法或属性时才创建它的实例,不调用它的方法或属性则永远不创建它的实例。好处:性能优化,减小内存开销。

 ==================================================================================================================
如下是java代码实现:
接口: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.....

    还原精灵
    (19)还原精灵
    还原精灵类的软件一般常见于网吧,我们在网吧上网的时候不管使用一台电脑下过什么或者删除过什么,只要重启之后机器都会恢复成原来的样子,这种情况一般都是还原精灵的作用。相信有很多初学电脑的朋友都遇到过诸如系统崩溃、无法引导、病毒入侵和数据丢失等另他们头痛不已的难题,而在解决这些问题后,我们往往会发现我们硬盘上的数据已经被破坏或丢失了。正是因为这样,学习如何保护好电脑中的数据的正确性与完整性就成了我们的首...更多>>
    一键还原
    (30)一键还原
    西西软件园提供好用的一键还原工具合集下载,西西小编的电脑经常1、2个星期就需要一键还原一次,所以一款好用的一键还原工具对西西小编来说很重要,西西小编使用的一键还原精灵,非常不错哦,傻瓜式的系统备份还原免费工具,它具有安全、快速、保密性强、压缩率高、兼容性好等特点,特别适合电脑新手和担心操作麻烦的人使用。不修改硬盘分区表,安装卸载倍加放心,自动选择备份分区,无需担心空间是否够用。完美支持多个分区备份还...更多>>
    备份还原
    (47)备份还原
    西西软件园提供最好用的系统备份还原软件,系统备份还原软件功能强大,效率高:快速还原,昨日重现,若感染病毒木马或系统崩溃,快速恢复到健康状态;在Win32(64)、WinPE、DOS下对任意分区进行一键备份、恢复的绿色无污程序,支持ISO文件、光盘、U盘里的GHO文件硬盘安装。...更多>>
    • ghost3212.0.0.7031 绿色版

      11-15 / 1.5M

      推荐理由:不错的工具,让你感觉回到了DOS时代,大名鼎鼎的硬盘备份工具,它可以把一个磁盘上的全部内容复制到另外一个
    • 影子系统2011最新版

      02-14 / 2.1M

      推荐理由:影子系统Returnil System Safe Pro 2011Returnil System Safe Pro 2011是瑞泰尼尔公司采用最新虚拟技术实现
    • Gho文件浏览工具(Symantec Ghost E

      10-17 / 10.1M

      推荐理由:SymantecGhost是大名鼎鼎的硬盘备份工具,它可以把一个磁盘上的全部内容复制到另外一个磁盘上,也可以把磁盘
    • 大地一键还原备份工具V2版

      04-14 / 3.4M

      推荐理由:提供多种环境下的操作:win32、DOS,支持WINxp-Win7操作系统备份还原等功能,完美支持WIN7(隐藏分区等环境下
    • Ghost 8.3 和 Ghost11.5 合集绿色汉

      05-15 / 15.4M

      推荐理由:一、分区备份  使用Ghost进行系统备份,有整个硬盘(Disk)和分区硬盘(Partition)两种方式。在菜单中点
    • 雨林木风 OneKey GhostV13.5.23.20

      05-27 / 6.0M

      推荐理由:一、详细说明: 1、默认核心是 Ghost 11.5,可自定义 Ghost 版本 2、程序默认对当前系统所在分区进行备份、
    联想一键恢复
    (15)联想一键恢复
    联想一键恢复是专用于联想电脑的一键恢复软件,可以恢复为出厂系统,可以做系统备份,有的版本可以进行杀毒和随机软件安装。联想一键恢复详细介绍:联想一键恢复系统可用来备份系统分区(C分区)的数据并在需要的时候使用此备份进行系统恢复。在Windows操作系统下,可以创建整个系统分区的备份并将备份文件存储在本地硬盘或者外部存储设备上。除此之外,还可以创建恢复光盘,用于从光盘启动和恢复系统。如果操作系统无法正常加载,...更多>>
    ghost
    (29)ghost
    西西软件园提供最好用的一键GHOST工具,GHOST一键GHOS适应各种用户需要,既可独立使用,又能相互配合.主要功能包括:一键备份C盘;一键恢复C盘;中文向导;GHOST一键GHOST可轻易进行系统还原,只需按一下"K"键,就能实现全自动无人值守操作,系统还原就这么简单!...更多>>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)