2012-01-10 25 views
9

Obecnie dokonujemy przeglądu kodu rzeczy przejętych z innego zespołu i mamy jedną wątpliwość co do stosowania SRP i jego związku z anemicznym lub bogatym modelem domeny (zgodnie z definicją Martina Fowlera). Koncepcja modelu Rich Domain ma mieć inteligentny obiekt, który może nie tylko ustawić/uzyskać jego właściwości, ale także może wykonać bardziej skomplikowaną logikę biznesową. Ciekawe, jak to pasuje do SRP?Zasada pojedynczej odpowiedzialności odnosi się do anemic/rich domain model?

Załóżmy, że moja klasa modelu ma pewne właściwości, które mogą narazić te rekwizyty i podać kilka prostych obliczeń dotyczących ich właściwości. Następny wymogiem jest, aby mieć możliwość przechowywania tego obiektu dane w pamięci jakiegoś przedmiotu, który nie jest pod moją kontrolą, jak to: metoda

class MyObject { 
    // get set 
    // parse sth 

} 

Przechowywać w przechowywaniu

storage.store(key, object); 

Czy nie naruszają SRP jeśli MyObject ma taką samą metodę przechowywania, jak ta, z tego pov to dobry pomysł, aby móc przechowywać jej stan. Innym sposobem może być wprowadzenie rodzaju usługi tutaj i to tak zrobić:

public StorageService { 
    private Storage; 
    // constructor here 
    .... 
    public void store(MyObject myobj); 
} 

Czy możesz wskazać mi jakieś linki mogę przeczytać o tym problemie? Znalazłem jeden wątek na SO tutaj, ale to nie odpowiada całkowicie na moje pytanie.

Jak jest rozwiązany w DDD? Modele w DDD są z definicji bogate i mogą być postrzegane jako mające zbyt wiele obowiązków.

+3

To może być zbyt dosłowna interpretacja SRP. Ignoruj ​​wuja Boba i idź do "spójności". –

+0

Jak zauważono w mojej odpowiedzi, jeśli Storage jest stabilny i abstrakcyjny (powiedzmy, standardowy JSON, XML, interfejs RDB), to IMO nie ma absolutnie żadnego problemu z pójściem na spójność i umieszczenie go w modelu domeny. – user949300

Odpowiedz

6

Bogaty model domeny (RDM) oznacza, że ​​logiczny regulującego modelu zachowanie należy w modelu, w przeciwieństwie do modelu traktowania, takich jak dane z pobierające/ustawiające. Nie oznacza to, że wszystkie elementy, w tym trwałość, bezpieczeństwo, sposób wyświetlania modelu w GUI itp., Muszą znajdować się w modelu.

RDM i SRP idą ramię w ramię, nie kłócą się ze sobą.

Naruszenie SRP/RDM:

Car { 
    // possibly violates SRP 
    storeInDatabase(); 
    // smells like anemic domain model 
    getEngineState(); 
} 

Po SRP/RDM:

// usings aspects to remove cross-cutting concerns from the model and follow SRP 
@DatabaseSerializable 
Car { 
    // rich domain model encapsulates engine state and exposes behavior 
    drive();    
} 
+1

Jeśli masz samochód z wieloma innymi metodami oprócz tylko Drive(), na przykład SwitchOn(), SwitchOff(), Turn(), Brake(), PlanRoute(), masz RDM, ale nie masz SRP. Im bardziej bogata jest twoja klasa z zachowaniem, tym bardziej dotyczy ona SRP. Są to przeciwne pomysły. –

+0

RDM oznacza, że ​​model powinien zawierać logikę domeny. SRP oznacza, że ​​twoje zajęcia powinny być odpowiedzialne za jedną rzecz - w przypadku modelu oznacza to "zawierającą logikę domeny" i niezawierającą kodu serializacyjnego lub kodu otwierającego połączenie internetowe, itp. –

+0

Jestem świadomy znaczenia. JuanZe mówi najlepiej: "Modele w DDD są z definicji bogate i mogą być postrzegane jako mające zbyt wiele obowiązków". Innymi słowy, nie jest łatwo zaimplementować prawdziwie bogatą całość, bez tego bytu mającego zbyt wiele obowiązków (więcej niż 1). O ile oczywiście nie wrzucamy do niej jednoosobowych usług/obiektów, w takim przypadku jest to granica ADM. –

4

"Modele w DDD są z definicji bogate i mogą być postrzegane jako mające zbyt wiele obowiązków" to uproszczona interpretacja DDD. Zawsze zależy to od tego, jak dobre są Twoje modele. Można tworzyć złe modele za pomocą DDD (na przykład tworzenie obiektów o zbyt dużej responsywności lub tworzenie modeli anemicznych). DDD i SRP to dwie dobre praktyki, podobnie jak refaktoryzacja, TDD i wiele innych, ale powinieneś uzupełnić ich użycie o swoje doświadczenie i osąd (lub czyjeś inne). Wszystko ma swoje zalety i wady, nie popadaj w dogmat do stosowania jakiejkolwiek praktyki.

3

@Garrett Hall

I trochę zgadzam się z wyciągu „RDM i SRP przejść ręka w rękę, nie kłócą się ze sobą."Z mojego doświadczenia wynika, że ​​kiedy SRP jest przeceniony, prowadzi to do anemicznego modelu domeny." Nie, nie możemy zrobić, ani nawet pomóc w utrzymaniu jakiegokolwiek oporu, nie, nie możemy zrobić 21-CFR11, nie, nie możemy nawet wiem co to GUI jest ...”i klasa kończy się robi nic i po prostu mieć anemiczne domeny modelu.

a jeśli RDM jest przecenić (to kierunek/error staram się wpaść) następnie SRP kompletnie spada z drogi i w końcu zauważysz, że twoja klasa ma 100 metod i najwyraźniej robi zbyt wiele. ciężko i często wiąże się z większymi uczuciami i polityką w twoim zespole niż technicznym doświadczeniem lub zasady.

"Poznaj siebie". Jeśli jesteś podobny do mnie i masz skłonność do zbyt skomplikowanych zajęć, bądź świadomy. A kiedy zobaczysz czyjąś klasę, która wygląda na zbyt skomplikowaną nawet dla ciebie, to duża czerwona flaga. Podobnie, jeśli wiesz, że jesteś dość hardcorowy w stosunku do SRP i widzisz klasę, która wygląda na anemię nawet według twoich standardów, to jest to główny zapach kodu.

Teraz, nieco odpowiadając na pytanie OP o Storage, myślę, że wiele zależy od tego, jak stabilne, standardowe i abstrakcyjne jest Storage. Jeśli Storage było standardową abstrakcją XML, CSV lub RDB, nie mam absolutnie żadnego problemu z obiektami, które wiedzą, jak się przechowywać.

+0

SRP mówi, że klasa ma jeden powód do zmiany, a to oznacza jedno źródło powodu do zmiany. Jeśli więc dla obiektu istnieją różne zachowania, należy je rozdzielić na różne klasy, a te klasy (które są usługami w DDD) należą do modelu domeny. –

Powiązane problemy