天天看点

延迟加载(Lazy Load)

一个对象,它虽然不包含所需要的所有数据,但是它知道怎么获取这些数据

延迟加载(Lazy Load)

设计专门的对象来把数据从DB中加载到内存中.

该对象可以完成在加载所需对象的同时,把与之相关的对象也一并加载了.

否则,必须显示加载所有所需的对象.

但是,加载一个对象可能会引起大量相关对象的加载.

当真正需要的对象只有几个时,会损害系统的性能.

延迟加载会暂时中止该关联加载过程.以使需要的数据在用到时才被加载.

运行机制

延迟初始化 Lazy initialization

思想.每次访问属性Field时,先检查是否为空..

必须保证field是自封闭的.也就是所有对该field的访问(即使来自类内部),都要通过get方法实现.

使用null来标记还未加载的field.

但是,当null时field的合法值时,需要其他符号来标记.

优点是简单.

但是会在对象和DB之间增加了依赖关系.适合于活动记录,表数据入口,行数据入口.

虚代理 Virtual Proxy

拥有实际类的外观.

实际上不包含任何东西.只有当其方法被调用时,才从DB加载适当的对象.

是对真实类的简单包装.

会引起标识问题.

同一个实对象拥有多个虚代理.它们会有不同的特征,但是又代表同一概念上的对象.应覆盖Equals方法来进行相等测试.

有时,必须创建大量的虚代理.

只对集合类用虚代理.因为集合的标识无关紧要.

延迟加载(Lazy Load)

好处,Domain类对Mapper如何进行延迟加载一无所知,甚至不知道延迟加载的存在.

值保持器 Value Holder

针对领域类.

用来包装其他对象的对象.要获取基对象,可以访问它得到.但是只有第一次访问它时,它才真正从DB读取Data.

缺点.类需要知道他的存在.而且丧失数据类型的显式性.

延迟加载(Lazy Load)

重影 Ghost

部分状态下的真实对象.

从DB加载对象时,它只包含ID.之后访问某个Field时,它会加载完全的状态.

虚代理或者重影不必完全没有数据.

对于某些需要快速获取或者常用到的数据.在加载代理或者重影时加载这些数据是有意义的("轻量对象").

继承会给延迟加载代理问题.

波动加载

产生了超出需要的DB访问.

例如,如果使用延迟加载填充一个集合,然后每次只访问其中的一个元素.会使每读取一个对象时访问一次DB.

解决是对类集合本身做延迟加载,而在加载类集合时,一次加载所有内容.

面向方面编程

可以将延迟加载置于一个单独的方面,以能够独立地改变延迟加载策略.

不同的用例和不同的延迟加载策略配合.为了获取最大效率,需要为特定的用例加载恰当的对象子图.

理论上需要一系列延迟程度不同的延迟加载对象.太复杂.

但是,通常只有两个:完全加载,用于识别用途的加载.

使用时机

完全取决于加载一个对象时,需要从DB读取多少Data和DB调用的次数.

只有当Field需要另外的DB访问时才考虑使用.