2012-10-25 17 views
8

Piszę system w PHP, który ma napisać do trzech warstw trwałość:PHP DataMapper z wielu warstw utrwalania

  • jedna usługa internetowa
  • dwóch baz danych (jeden mysql jeden mssql)

Powodem tego są starsze systemy i nie można ich zmienić.

Chcę używać wzorca DataMapper i staram się ustanowić najlepszy sposób, aby osiągnąć to, co chcę. Mam interfejs jak następuje:

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

Poniżej jest jakiś wymyślony i wyciąć kod dla zwięzłości:

<?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); 
    } 
} 
?> 

Moje pytanie jest to, że ponieważ istnieją trzy warstwy trwałości, nie będzie również dlatego może być potrzeba trzech programistów dla każdego. Chciałbym stworzyć interfejs inspirowany czystym wzorem, aby to działało.

widzę go jako posiadające trzy opcje:

  1. wstrzyknąć trzy mappers na służbę i nazywają utworzyć na każdym
  2. $ _mapper jest tablicą/zbierania i iteracje poprzez nazywając je utworzyć na każdym
  3. $ _mapper jest rzeczywiście obiekt kontenera, który działa jako dalszego pełnomocnictwa oraz wzywa utworzyć na każdym

Coś wydaje mi się źle ze sobą t hese solutions i docenią wszelkie opinie/uznane wzorce projektowe, które mogą do tego pasować.

Odpowiedz

2

Musiałem rozwiązać podobny problem, ale bardzo wiele lat temu w czasach PEAR DB. W tym konkretnym przypadku zachodziła potrzeba replikacji danych w wielu bazach danych.

Nie mieliśmy problemu z różnymi bazami danych posiadającymi różne odwzorowania, więc było to trochę prostsze.

To, co zrobiliśmy, to elewacja klasy DB i nadpisanie funkcji getResult (lub jakkolwiek ją wywołano). Funkcja ta następnie analizowała SQL i jeśli była odczytana - wysyłałaby go do jednego z kopii, a gdyby był napisany, wysyłałaby go do wszystkich.

To naprawdę działało naprawdę dobrze na bardzo mocno wykorzystanej stronie.

Na tym tle sugerowałbym, aby w pełni uwzględnić wszystkie operacje związane z utrwalaniem. Po wykonaniu tej czynności szczegóły realizacji są mniej istotne i można je zmienić w dowolnym momencie.

Z tego punktu widzenia każdy z pomysłów na wdrożenie wydaje się rozsądnym podejściem. Są jednak różne rzeczy, o których warto pomyśleć.

  • Co się stanie, jeśli jeden z backendów zgłosi błąd?
  • Jaki jest wpływ wydajności na pisanie na trzech serwerach baz danych?
  • Czy te zapisy odbywać asynchronicznie (jeśli tak, to na pierwsze pytanie zadać ponownie)

Istnieje potencjalnie inny sposób na rozwiązanie tego problemu, jak również. To jest użycie procedur przechowywanych. Jeśli masz podstawowy serwer bazy danych, możesz napisać wyzwalacz, który po zatwierdzeniu (lub w tym miejscu) łączy się z inną bazą danych i synchronizuje dane.

Jeśli aktualizacja danych nie musi być natychmiastowa, można uzyskać podstawową bazę danych do zapisywania zmian i mieć inny skrypt, który regularnie "dostarcza" te dane do innego systemu. Ponownie, kwestia błędów będzie musiała być wzięta pod uwagę.

Mam nadzieję, że to pomoże.

0

Myślę, że opcja nr 2 jest najlepsza w mojej opinii. Poszedłbym z tym. Gdybyś miał 10 lub więcej twórców map niż opcja 3, sensownym byłoby przesunięcie logiki tworzenia do samego programu odwzorowującego, ale ponieważ masz rozsądną liczbę twórców map, lepiej jest po prostu je wprowadzić i powtórzyć je. Rozszerzenie funkcjonalności poprzez dodanie kolejnego programu odwzorowującego byłoby kwestią dodania 1 linii do konfiguracji wtrysku zależności.

1

Po pierwsze, trochę terminologii: to, co nazywacie trzema warstwami, to w rzeczywistości trzy moduły, a nie warstwy. Oznacza to, że masz trzy moduły w warstwie trwałości.

Podstawowym założeniem tego problemu jest: MUSISZ mieć trzy różne logiki trwałości, odpowiadające trzem różnym źródłom pamięci. Jest to coś, czego nie można uniknąć. Dlatego pytanie brzmi tylko, jak wywołać operację zapisu na tych modułach (zakładając, że do odczytu nie trzeba wywoływać wszystkich trzech, lub jeśli tak, to jest to osobne pytanie w dowolny sposób).

Z trzech wymienionych opcji, moim zdaniem pierwszy jest lepszy. Ponieważ jest to najprostszy z trzech. Pozostałe dwa będą nadal wymagały wywoływania trzech modułów osobno, z dodatkową pracą polegającą na wprowadzeniu kontenera lub jakiejś struktury danych. Nadal nie możesz uniknąć wywoływania gdzieś trzech modułów.

Jeśli pracujesz z pierwszą opcją, to oczywiście musisz pracować z interfejsami, aby zapewnić jednolite abstrakcje dla użytkownika/klienta (w tym przypadku usługi).

Chodzi mi o to, że: 1. Jest to nieodłączna złożoność problemu, której nie można dalej uprościć. 2. Pierwsza opcja jest lepsza, ponieważ dwie pozostałe sprawiają, że rzeczy są bardziej złożone, a nie proste.

Powiązane problemy