Warstwa biznesowa – model domeny (domain model pattern)

Przyszedł czas na opisanie najbardziej złożonego wzorca warstwy biznesowej – modelu domeny (DM). Jeśli nie znacie dobrze wzorca opisanego w poprzednich postach (aktywny rekord) nie zaczynajcie nawet próbować zrozumieć DM ponieważ jest on po prostu rozszerzeniem AR.

Na początek kilka faktów. DM jest wzorcem w pełni obiektowym, wykorzystującym wszelkie dobrodziejstwa programowania obiektowego (dziedziczenie, polimorfizm itp.). DM w przeciwieństwie do AR nie jest wzorcem zorientowanym na bazę danych. Scenariusz wykorzystania AR często wyglądał tak, że programista tworzył najpierw bazę danych dla danego problemu biznesowego a dopiero potem obiekty biznesowe AR. W przypadku DM podejście wygląda zupełnie inaczej. Problem biznesowy kompletnie abstrahuje od bazy danych. Programista tworzy najpierw klasy rozwiązujące problem biznesowy a baza danych jest już potem tylko dodatkiem.

Podobnie jak AR, klasy DM przechowują informacje na poziomie wiersza. Przykładową klasą DM może być więc:

public class Client: Person
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public abstract int GetDiscount();
}

Sama klasa wygląda tak jak AR. Jednak trzeba być świadomym kilku faktów:

  1. Klasa nic nie wie o docelowej bazie danych. Obiekt takiej klasy po prostu reprezentuje kawałek logiki biznesowej. Kwestia zapisu jest już tylko sprawą techniczną i jak to zostanie zrobione nie należy to do kompetencji DM,
  2. Klasa jest typu POCO. Klasy POCO muszą spełniać kilka warunków m.in nie mogą zawierać atrybutów czy  z góry narzuconych interfejsów zdefiniowanych przez ORM. Innymi słowy jest to po prostu czysta klasa c#,
  3. Klasa Client dziedziczy po Person. Jest to jak najbardziej wskazane w DM,
  4. Zawiera abstrakcyjną metodę – tak jak wspomniałem DM ze względu na pełną niezależność od bazy danych może wykorzystywać pełen zestaw dobrodziejstw programowania obiektowego,
  5. Klasa Client nie musi odpowiadać jednej tabeli w bazie danych. Często pojedyncza klasa DM mapowana jest na wiele tabel. Występuje tu pełna niezależność ze względu na fakt, że zapisem do bazy nie zajmują się już obiekty biznesowe.

Zalety:

  1. Zapobiega duplikacji logiki,
  2. Rozłożenie problemu na obiekty biznesowej powoduje wzrost czytelności kodu,
  3. Niezależność od źródła danych,
  4. Obiekty są typu POCO, zatem mogą korzystać z rozszerzeń OOP,
  5. Znacznie ułatwienia w wykonywaniu testów jednoskokowych ze względu na oddzielenie obiektów odo źródła danych.

Wady:

  1. Bardzo czasochłonna implementacja,
  2. Rozdrobniony interfejs,
  3. Potrzeba wykorzystania dodatkowego wzorca (remote facade) w celu wyeksponowania logiki przez web service.

Nie będę pisać konkretnego kodu ponieważ wartość metod zależy już od budowanego systemu. Zamiast tego uważam, że lepszym wyjściem jest pokazanie diagramu klas. W końcu nie ważne co znajduje się w środku tylko jaka jest relacjami pomiędzy klasami. Poniżej krótki przykład DM w akcji dla systemu sprzedaży:

image

Leave a Reply

Your email address will not be published.