2012-10-25 38 views
8

我寫在PHP的系統具有寫三個持久層:PHP DataMapper的多個持久層

  • 一個web服務
  • 兩個數據庫(一個MySQL的一個MSSQL)

原因是遺留系統,無法更改。

我想使用DataMapper模式,我試圖建立最好的方式來實現我想要的。我有一個接口類似如下:

<?php 
    $service = $factory->getService()->create($entity); 
?> 

下面是一些做作和減少代碼簡潔:

<?php 
class Post extends AbstractService 
{ 
    protected $_mapper; 

    public function create(Entity $post) 
    { 
     return $this->_mapper->create($post); 
    } 
} 

class AbstractMapper 
{ 
    protected $_persistence; 

    public function create(Entity $entity) 
    { 
     $data = $this->_prepareForPersistence($entity); 
     return $this->_persistence->create($data); 
    } 
} 
?> 

我的問題是,因爲有三個持久層,將有也因此可能是一個每個需要三個映射器。我想要一個乾淨的設計模式啓發界面,使這項工作。

我認爲這是有三個選項:

  1. 進樣3名映射器到服務,並呼籲各
  2. $ _mapper創建是一個數組/集合,並通過他們遍歷每個
  3. 調用創建
  4. $ _mapper實際上是一個容器對象,作爲一個 進一步代理並呼籲各

創造的東西令我錯每個T的這些解決方案,並會欣賞任何反饋/認可的設計模式,可能適合這一點。

回答

2

我不得不解決類似的問題,但很多年前在PEAR DB的日子裏。在這種特殊情況下,需要跨多個數據庫複製數據。

雖然我們沒有使用不同映射的不同數據庫的問題,所以它稍微簡單一些。

我們所做的就是對DB類進行外觀並重寫getResult函數(或其他所謂的函數)。這個函數然後分析了SQL,如果它是一個讀 - 它會發送給一個支持,如果它是一個寫,它會發送給所有人。

對於一個使用率很高的網站來說,這確實很有效。

從這種背景下,我會建議完全使所有的持久性操作。一旦你這樣做了,實現細節就沒有什麼相關性,可以隨時更改。

從這個角度來看,您的任何實現想法都是一種合理的方法。儘管你會想到各種各樣的事情。

  • 如果其中一個後端拋出錯誤會怎麼樣?
  • 寫入三個數據庫服務器對性能的影響是什麼?
  • 能否寫入被異步完成(如果是的話,再次詢問的第一個問題)

有潛在的另一種方式來解決這個問題爲好。那就是使用存儲過程。如果你有一個主數據庫服務器,你可以編寫一個觸發器,在commit(或其附近)連接到另一個數據庫並同步數據。

如果數據更新不需要立即進行,您可以讓主數據庫記錄更改,並有另一個腳本將此數據定期「饋送」到另一個系統中。再次,錯誤的問題將需要考慮。

希望這會有所幫助。

0

我認爲選項#2是我認爲最好的。我會去那。如果你喜歡10+以上的映射器而不是選項#3將創建邏輯轉移到映射器本身是有意義的,但是由於你有合理數量的映射器,只需要將它們注入並遍歷它們就更有意義。通過添加另一個映射器來擴展功能只需將1行添加到您的依賴注入配置即可。

1

首先,有點術語:你稱之爲三層,實際上是三層模塊,而不是層。也就是說,持久層中有三個模塊。

現在,這個問題的基本前提是:你必須有三種不同的持久性邏輯,對應於三種不同的存儲源。這是你無法避免的。因此,問題在於如何在這些模塊上調用寫操作(假設讀取的內容不需要全部調用這三個模塊,或者如果這樣做,那麼這是一個單獨的問題)。

從你列出的三個選項中,我認爲第一個更好。因爲這是三者中最簡單的。另外兩個,仍然需要分別調用三個模塊,引入一個容器或某種數據結構。你仍然無法避免在某處調用三個模塊。

如果使用第一個選項,那麼您顯然需要使用接口來爲用戶/客戶端(在本例中爲服務)提供統一的抽象。

我的觀點是: 1.他們是你的問題的固有複雜性,你不能再簡化。 2.第一種選擇是更好的,因爲其他兩個,使事情更復雜,而不是簡單。