我有一個現實世界的問題,我將嘗試將其抽象爲一個說明性示例。具有多個存儲選項的持久數據樹的模式?
所以,想象我在一棵樹,在父對象可以訪問孩子的數據對象,孩子們可以訪問家長:這是在兩個數據存儲持久
// 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;
}
}
這樣我可以有一個每個數據存儲的映射器,並從我想要的映射器構建對象,然後使用我想要的映射器保存它。
這裏有一個循環引用,但我想這不是一個問題,因爲大多數語言只能存儲對象的內存引用,所以實際上不會有無限的數據。
這樣做的問題是,每次我想建立一個新的Top
,Middle
或Bottom
,它需要建立該對象的Parent
或Children
物業內的整個對象樹,所有的數據存儲要求和內存使用情況這需要。在現實生活中,我的樹比這裏所代表的要大得多,所以這是一個問題。
請求在對象
在該對象請求其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服務。
這也讓我感到不安,因爲數據對象本身不再不知道數據源。我們引入了一個新的依賴關係,更不用說循環依賴關係了,這使得測試更加困難。對象現在掩蓋了與數據庫的通信。
其他解決方案
是否有可能採取多個商店問題保健,而且也意味着我不需要建立/任何其他解決方案要求每次所有的數據?
我認爲複合只適用於某些類型的樹 - 「當客戶應該忽略物體和單個物體的組成之間的區別」(來自維基百科)。我的樹不是這種情況。收藏絕對不像個人。至於「建造者」模式,它說「同一個建造過程可以創建不同的表示」。我想要的是相反的 - 不同的構建過程(從不同的數據格式)產生相同的表示。我將閱讀關於在視圖中打開會話。 –
Re:爲什麼我需要中產階級 - 這是插圖的一部分。我只是說我在我的樹上有既有父母又有孩子的物品。 –
我提出Composite的原因是你基於位置邏輯顯示了不同的類,所以Composite可以讓這些差異消失。 – Rob