一個對象,它雖然不包含所需要的所有資料,但是它知道怎麼擷取這些資料
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyADO3YzNxATNzcTMwMTOwgTMwIzLcVDM0EDMy8CXvZmbp9CXt92YuUGZvNWatFWbuU2Zh1Wavw1LcpDc0RHaiojIsJye.png)
設計專門的對象來把資料從DB中加載到記憶體中.
該對象可以完成在加載所需對象的同時,把與之相關的對象也一并加載了.
否則,必須顯示加載所有所需的對象.
但是,加載一個對象可能會引起大量相關對象的加載.
當真正需要的對象隻有幾個時,會損害系統的性能.
延遲加載會暫時中止該關聯加載過程.以使需要的資料在用到時才被加載.
運作機制
延遲初始化 Lazy initialization
思想.每次通路屬性Field時,先檢查是否為空..
必須保證field是自封閉的.也就是所有對該field的通路(即使來自類内部),都要通過get方法實作.
使用null來标記還未加載的field.
但是,當null時field的合法值時,需要其他符号來标記.
優點是簡單.
但是會在對象和DB之間增加了依賴關系.适合于活動記錄,表資料入口,行資料入口.
虛代理 Virtual Proxy
擁有實際類的外觀.
實際上不包含任何東西.隻有當其方法被調用時,才從DB加載适當的對象.
是對真實類的簡單包裝.
會引起辨別問題.
同一個實對象擁有多個虛代理.它們會有不同的特征,但是又代表同一概念上的對象.應覆寫Equals方法來進行相等測試.
有時,必須建立大量的虛代理.
隻對集合類用虛代理.因為集合的辨別無關緊要.
好處,Domain類對Mapper如何進行延遲加載一無所知,甚至不知道延遲加載的存在.
值保持器 Value Holder
針對領域類.
用來包裝其他對象的對象.要擷取基對象,可以通路它得到.但是隻有第一次通路它時,它才真正從DB讀取Data.
缺點.類需要知道他的存在.而且喪失資料類型的顯式性.
重影 Ghost
部分狀态下的真實對象.
從DB加載對象時,它隻包含ID.之後通路某個Field時,它會加載完全的狀态.
虛代理或者重影不必完全沒有資料.
對于某些需要快速擷取或者常用到的資料.在加載代理或者重影時加載這些資料是有意義的("輕量對象").
繼承會給延遲加載代理問題.
波動加載
産生了超出需要的DB通路.
例如,如果使用延遲加載填充一個集合,然後每次隻通路其中的一個元素.會使每讀取一個對象時通路一次DB.
解決是對類集合本身做延遲加載,而在加載類集合時,一次加載所有内容.
面向方面程式設計
可以将延遲加載置于一個單獨的方面,以能夠獨立地改變延遲加載政策.
不同的用例和不同的延遲加載政策配合.為了擷取最大效率,需要為特定的用例加載恰當的對象子圖.
理論上需要一系列延遲程度不同的延遲加載對象.太複雜.
但是,通常隻有兩個:完全加載,用于識别用途的加載.
使用時機
完全取決于加載一個對象時,需要從DB讀取多少Data和DB調用的次數.
隻有當Field需要另外的DB通路時才考慮使用.