2010-01-08 12 views
6

W aplikacji, która następnie Domain Driven Design, gdzie masz następujące rodzaje pojęćbuforowanie Kod Lokalizacja w Domain Driven Design

  1. Repozytorium która zajmuje się dostęp do bazy danych
  2. usługę aplikacja koordynuje interakcje między danymi wejściowymi a obiektami o wartości itp.

gdzie ogólnie można umieścić kod pamięci podręcznej w celu zniesienia kosztownego połączenia z bazą danych?

Widziałem bazy kodu, które po prostu cache w całym miejscu i trudno jest monitorować wykorzystanie pamięci i trudne do zapewnienia wskazówek dla innych programistów.

Proszę zrozumieć, że wiem, że należy buforować dane tylko wtedy, gdy jest to konieczne, po prostu zadaję ogólne pytanie.

Odpowiedz

10

Cudowną rzeczą w przypadku abstrakcyjnych repozytoriów jest to, że można użyć narzędzia Decorator pattern, aby zaimplementować takie zagadnienia przekrojowe, jak buforowanie.

Jako przykład podawany był IMyRepository interfejs, można utworzyć MyCachingRepository jak ten pseudo kod:

public class MyCachingRepository : IMyRepository 
{ 
    private readonly IMyRepository repository; 

    public MyCachingRepository(IMyRepository repository) 
    { 
     if(repository == null) 
     { 
      throw new ArgumentNullException("repository"); 
     } 

     this.repository = repository; 
    } 

    public Foo SelectFoo(int id) 
    {  
     Foo foo = ... // attempt to get foo from cache 

     if // foo is not it cache 
     { 
      foo = this.repository.SelectFoo(id); 
      // save foo in cache 
     } 
     return foo; 
    } 
} 

W tym przykładzie GetFoo jest zdefiniowany przez IMyRepository. Zwróć uwagę, że dekorowane repozytorium jest wywoływane tylko wtedy, gdy element nie zostanie znaleziony w pamięci podręcznej.

Jest to zgodne z Single Resposibility Principle, ponieważ rzeczywista implementacja buforowania może koncentrować się na pobieraniu i zapisywaniu danych, podczas gdy buforujący dekorator może koncentrować się na buforowaniu. Pozwala to na zmianę obu niezależnie od siebie.

W naszym obecnym projekcie wykorzystaliśmy to podejście, a co jest szczególnie miłe, że możemy to zrobić po namyśle, nie dotykając nawet oryginalnych repozytoriów. To jest w duchu Open/Closed Principle.

+0

Fajnie, dziękuję - przyjrzę się temu bliżej. – DownChapel

+0

Dziękuję za wzmiankę o wszystkich zaangażowanych zasadach projektowania, to prawdziwa niespodzianka. Już znam ten projekt, ale twoja odpowiedź naprawdę podkreśla prawdziwe piękno tego podejścia! –

+0

Czy to oznacza, że ​​CachingRepository i FooRepository mają ten sam interfejs, ale różne implementacje? Czy to oznacza, że ​​wywołujący wywołuje cachingRepo bezpośrednio, a nie FooRepository? – Pascal

2

Umieściłbym go w repozytoriach. Repozytoria powinny być zdefiniowane przez umowę, a użycie pamięci podręcznej powinno być ukryte za tą umową, aby było przejrzyste dla konsumenta repozytorium.