0

我有一個現實世界的問題,我將嘗試將其抽象爲一個說明性示例。具有多個存儲選項的持久數據樹的模式?

所以,想象我在一棵樹,在父對象可以訪問孩子的數據對象,孩子們可以訪問家長:這是在兩個數據存儲持久

// Interfaces 
interface IParent<TChild> { List<TChild> Children; } 
interface IChild<TParent> { TParent Parent; } 

// Classes 
class Top : IParent<Middle> {} 
class Middle : IParent<Bottom>, IChild<Top> {} 
class Bottom : IChild<Middle> {} 

// Usage 
var top = new Top(); 
var middles = top.Children; // List<Middle> 
foreach (var middle in middles) { 
    var bottoms = middle.Children; // List<Bottom> 
    foreach (var bottom in bottoms) { 
     var middle = bottom.Parent; // Access the parent 
     var top = middle.Parent; // Access the grandparent 
    } 
} 

所有這三個數據對象有屬性(如數據庫和Web服務),他們需要反映並與商店同步。有些對象只從Web服務請求,有些只能寫入。

數據映射

我最喜歡的數據訪問模式是Data Mapper,因爲它完全分離的數據從通信對象本身與數據存儲:

class TopMapper { 
    public Top FetchById(int id) { 
     var top = new Top(DataStore.TopDataById(id)); 
     top.Children = MiddleMapper.FetchForTop(Top); 
     return Top; 
    } 
} 

class MiddleMapper { 
    public Middle FetchById(int id) { 
     var middle = new Middle(DataStore.MiddleDataById(id)); 
     middle.Parent = TopMapper.FetchForMiddle(middle); 
     middle.Children = BottomMapper.FetchForMiddle(bottom); 
     return middle; 
    } 
} 

這樣我可以有一個每個數據存儲的映射器,並從我想要的映射器構建對象,然後使用我想要的映射器保存它。

這裏有一個循環引用,但我想這不是一個問題,因爲大多數語言只能存儲對象的內存引用,所以實際上不會有無限的數據。

這樣做的問題是,每次我想建立一個新的TopMiddleBottom,它需要建立該對象的ParentChildren物業內的整個對象樹,所有的數據存儲要求和內存使用情況這需要。在現實生活中,我的樹比這裏所代表的要大得多,所以這是一個問題。

請求在對象

在該對象請求其Parent S和Children本身:

class Middle { 
    private List<Bottom> _children = null; // cache 
    public List<Bottom> Children { 
     get { 
      _children = _children ?? BottomMapper.FetchForMiddle(this); 
      return _children; 
     } 
     set { 
      BottomMapper.UpdateForMiddle(this, value); 
      _children = value; 
     } 
    } 
} 

我認爲這是repository pattern的一個例子。那是對的嗎?

該解決方案看起來很整潔 - 數據只在需要時從數據存儲中獲取請求,並且之後如果您想再次請求數據,則會將其存儲在對象中,從而避免了進一步的請求。

但是,我有兩個不同的數據源。有一個數據庫,但也有一個Web服務,我需要能夠從Web服務創建一個對象並將其保存回數據庫,然後再從數據庫請求它並更新Web服務。

這也讓我感到不安,因爲數據對象本身不再不知道數據源。我們引入了一個新的依賴關係,更不用說循環依賴關係了,這使得測試更加困難。對象現在掩蓋了與數據庫的通信。

其他解決方案

是否有可能採取多個商店問題保健,而且也意味着我不需要建立/任何其他解決方案要求每次所有的數據?

回答

0

你真的在問兩個無關的問題。是的,存儲庫模式應該導致從商店中提取項目本身(實體)對商店一無所知。所以你通常有實施CRUD的倉庫,每次你需要一個實體時,你可以從那裏獲得它們。我沒有看到製圖員的角度,也不知道爲什麼你需要那個中產階級......?

第二個問題是如何處理可能不是一次構建的大樹。既然你用設計模式標記了這個,建議樹類應該實現Composite而不是「映射器」,你應該有一個Builder。然後,該構建器必須能夠分階段構建事物。這是一個有趣的問題。在依賴注入領域,OpenSessionInView使這個問題更加複雜。

試着想一個版本,不會有類僅僅位置的區別,我認爲複合材料將做到這一點。

+0

我認爲複合只適用於某些類型的樹 - 「當客戶應該忽略物體和單個物體的組成之間的區別」(來自維基百科)。我的樹不是這種情況。收藏絕對不像個人。至於「建造者」模式,它說「同一個建造過程可以創建不同的表示」。我想要的是相反的 - 不同的構建過程(從不同的數據格式)產生相同的表示。我將閱讀關於在視圖中打開會話。 –

+0

Re:爲什麼我需要中產階級 - 這是插圖的一部分。我只是說我在我的樹上有既有父母又有孩子的物品。 –

+0

我提出Composite的原因是你基於位置邏輯顯示了不同的類,所以Composite可以讓這些差異消失。 – Rob

相關問題