2009-11-02 20 views
12

Szukam prostego przykładu, aby zilustrować korzyści wynikające z używania bogatego modelu domeny. Idealnie, chciałbym przed i po liście kodów (które powinny być tak krótkie, jak to możliwe).Czy istnieje przykład bogatego modelu domeny?

Wcześniejsza lista kodów powinna wskazywać problem rozwiązywany za pomocą anemicznego modelu domeny i wiele względnie proceduralnych kodów warstwy usług, a lista kodów po kodzie powinna pokazywać ten sam problem, który jest rozwiązywany przy użyciu bogatej, obiektowej orientacji. model domeny.

Idealnie kod powinien znajdować się w Javie lub Groovy, ale może to zrobić coś całkiem podobnego (np. C#).

+2

Niestety jest to bardzo trudne do opisania korzyści w krótkim odpowiedź. Jeśli piszesz system, który zawiera dużo zachowań, zamiast wstawiania/aktualizowania/usuwania, możesz skorzystać z enkapsulacji logiki w jednym zestawie klas (modele twojej domeny). Prawdopodobnie nie zobaczysz korzyści, dopóki nie uzyskasz wystarczająco dużego rozwiązania, a logika domeny jest wystarczająco złożona. W takim przypadku bardzo dobrze jest zamknąć logikę domeny w jednym miejscu. –

Odpowiedz

-5

To nie odpowiada dokładnie na twoje pytanie, ale widzę przeciwieństwo projektowania opartego na domenie jako projektu opartego na bazie danych. W projektowaniu opartym na bazie danych najpierw tworzony jest schemat bazy danych, a następnie tworzone są zajęcia z pełną wiedzą o tym, jak wygląda schemat. Zaletą jest to, że lepiej rozumiesz, co dzieje się pod maską i minimalizujesz skutki niedopasowania impedancji. Jednak wadą jest to, że schemat bazy danych, ponieważ jest bardziej relacyjny niż obiektowy, nie przekłada się bardzo na obiekty (na przykład, nie ma koncepcji kolekcji w relacyjnych bazach danych).

W projektowaniu opartym na domenie teoretycznie tworzysz obiekty danych tak jak każda inna klasa i traktujesz bazę danych po prostu jako warstwę trwałości. W terminologii Layman baza danych jest tylko kontenerem pamięci i nie obchodzi Cię, JAK obiekty są przechowywane, tylko że są one w jakiś sposób zapisane. Eliminuje to niedopasowanie impedancji i masz o co mniej martwić się. W praktyce jednak nadal musisz wiedzieć, w jaki sposób przechowywane są obiekty, i mogą występować problemy z wydajnością, gdy ORM, którego używasz, próbuje wypluć złożone zapytanie SQL.

Edit:

Oto przykład tego, co Domain-Driven Design powinno być, co do zasady. Powiedzmy, że masz klasę Person, podobnie jak (w języku C#):

public class Person 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Address Address { get; set; } 
    public ICollection<Person> Relatives { get; set; } 
    public Company Employer { get; set; } 
} 

Teraz w relacyjnej bazie danych, będzie to prawdopodobnie przekłada się na 3 stoły, stół osoby, stół adres i tabeli Spółki, z wiązka relacji między nimi. To jednak znacznie różni się od tego, jak programista widzi ten obiekt. Programista widzi go jako instancję obiektu Person z 4 parametrami, z których jeden to ICollection. Nie pasuje to bardzo dobrze do struktury tabeli bazy danych, stąd "niedopasowanie impedancji", lub w terminologii Laymena, różnica w rozmieszczeniu między modelem relacyjnym a modelem obiektu.

W Domain-Driven Design, byłbym w stanie to zrobić:

Person person = new Person(); 
// set each property to something 
Database.Save(person); 

Teraz obiekt osoba jest zapisana. mogę je odzyskać tak:

Person databasePerson = Database.Get<Person>(idOfPerson); 

i będzie to powrót mojego Person obiekt, tak jak to było wcześniej, jak uratowałem go. W ten sposób nie interesuje mnie sposób, w jaki zapisuje go databse, ani niepokój związany z niedopasowaniem impedancji. Po prostu zapiszę i pobierz w razie potrzeby.

To wszystko jednak w teorii. W praktyce prawdopodobnie będziesz musiał ręcznie określić "mapowanie" lub jak klasy będą wiedzieć, która tabela/kolumna w bazie danych pobiera dane. Może to być dość skomplikowane, gdy próbujesz mapować na bardziej złożone typy, takie jak słowniki i inne narzędzia ADT, a także gdy próbujesz pobrać dane z wielu tabel do jednej klasy.

+4

Nie sądzę, że jest to przykład bogatego modelu domeny, ponieważ domena, którą opisujesz, nie zawiera żadnego zachowania. – JasonTrue

+1

To nie jest bogata domena. W bogatej domenie prawdopodobnie nie będziesz miał żadnych seterów lub tylko kilku. – Martin

+0

Mówisz o mapowaniu relacyjnym obiektów, które jest zupełnie inną koncepcją. Twoja klasa Person zawiera strukturę danych, nic więcej. Potrzebujesz metod i enkapsulacji (ukrywania danych i implementacji), aby przekształcić ją w prawdziwy obiekt. – inf3rno

2

Myślę, że nikt nie zrobił tego rodzaju porównania, a gdyby tak było, to nie byłoby małe. Domain Driven Design próbuje rozwiązać złożoność, a prosty przykład nie zawiera złożoności.

Być może Domain Driven design Step by Step udzieli odpowiedzi.

+0

link jest nieaktualny .. – xenoterracide

3

dam ci prosty przykład realnej produkcji kodu:

Person.groovy:

List addToGroup(Group group) { 
    Membership.link(this, group) 
    return groups() 
    } 

Membership.groovy:

static Membership link(person, group) { 
    def m = Membership.findByPersonAndGroup(person, group) 
    if (!m) { 
     m = new Membership() 
     person?.addToMemberships(m) 
     group?.addToMemberships(m) 
     m.save() 
    } 
    return m 
} 

Ilekroć chcę aby związać osobę z grupą, mogę po prostu zrobić person.addToGroup (grupa)

kod proceduralny byłoby coś takiego, na kontrolerze:

def m = Membership.findByPersonAndGroup(person, group) 
if (!m) { 
     m = new Membership() 
     person?.addToMemberships(m) 
     group?.addToMemberships(m) 
     m.save() 
} 

Na pierwszy rzut oka można powiedzieć, że można owinąć że w funkcji i jesteś dobry, aby przejść. Ale zaletą bogatego projektu IMHO jest to, że jest on bliższy temu, co myślisz, a zatem jest bliższy racjonalizacji. W tym konkretnym przykładzie chcę tylko dodać osobę do grupy, a kod będzie właśnie czytał.

Jest to krótki przykład, na jaki się spytałeś, ale łatwo jest rozwinąć ten przykład i zobaczyć, jak budować złożone interakcje z odpowiednim modelowaniem domen.

Możesz również zobaczyć Transaction Script Martina Fowlera i Domain Model dla krótkiego wyjaśnienia tych dwóch wzorów, które uważam za związane z DDD.