Anemic domain model

Tuli tässä taas keskusteltua Martin Fowlerin ristiriitaisen vastaanoton saaneesta “anti-patternista”, nimittäin anemic domain modelista.

Osa ohjelmoijista nimittäin on sitä mieltä, että domain-luokkiin voi huoletta lisätä myös logiikkaa. Itse olen aina ollut vahvasti sillä kannalla, että logiikkaa ja dataa sisältävät luokat tulee pitää tiukasti erillään.

Otetaanpa esimerkki eräältä “anemic domain”-mallia vastustavalta sivustolta:

HUOM: Tämä EI siis ole meikäläisen kirjoittamaa koodia!

@javax.persistence.Entity
public class Acount {

@javax.persistence.Transient
private EmailService email;

@javax.persistence.Id
private Long id;
private float balance;

public void withdraw(float amount) {
if (amount>balance) {
email.sendOverdrawMessage(this);
}
balance-=amount;
}
...

Todella karseaa koodia. Ensinnäkin pahaa tekee floatin käyttö rahan käsittelyssä ja toisekseen servicen sijoittaminen domain-luokkaan. No, muutenkin esimerkki on aika kaukana reaalimaailmasta.. Service-kutsujen viljely domain-luokkien sekaan tekee logiikan seuraamisesta erittäin hankalaa ja aiheuttaa nähdäkseni syklisiä riippuvuuksia sekä mahdollisia muistivuotoja.

Otetaan yksinkertaisempi esimerkki:

Perinteinen, “anemic”-malli:

printer.print(document);

Ja anemic-mallin vastakohta (mikähän sen nimi sitten onkaan):

document.print();

Tässä tosiaan toteutetaan ajatusta “Don’t ask, tell”. Ongelmaksi vain muodostuu se, että ominaisuuksien lisääntyessä, domain-luokasta tulee jatkuvasti bloatimpi. Jos esimerkiksi lisätään dokumenttiin tallennusominaisuus, sähköpostin lähetysominaisuus, PDF-konversio-ominaisuus, tulee niistä kaikista uusi riippuvuus dokumenttiolion sisään. Miksi ihmeessä dokumentin pitäisi osata esimerkiksi tulostaa itsensä? Kuuluuko se dokumentin tehtäviin? Tämä sotii mielestäni separation of concerns-ajatusta vastaan.

Lisäksi joissain tapauksissa ongelmaksi muodostuu olion serialisointi verkon yli. Yht’äkkiä hajautetussa transaktiossa toimivat palvelut saavatkin domain-luokan mukana tukun riippuvuuksia epämääräiseen joukkoon palveluita..

Lisäksi tuossa jälkimmäisessä tosiaan tulee syklinen riippuvuus domain luokkien ja service-kerroksen kanssa:

client -> DocumentService.process(List documents) -> document.print() -> PrintService.print(document)

Perinteisessä mallissa domain-luokat taas eivät ole riippuvaisia service-kerroksesta:

client -> DocumentService.process(List documents) -> PrintService.print(document)

Itse kutsuisin Fowlerin aneemiseksi tituleeraamaa mallia vaikkapa “light-weight domain modeliksi”. Yksinkertaisuus kun ei mielestäni ole pahe koodissa.

No, paljon jäi sanomatta, mutta tällaisia mietteitä asiasta noin äkkiseltään tuli. Olisi ihan mielenkiintoista kuulla, että onko jollain menestystarinoita logiikan upottamisesta domain-malliin? Ja vanhoja entity beaneja en laske menestystarinaksi. :-)

3 kommenttia Heinäkuu 6th, 2007

Murhaajan ihailua

Pakko avautua. En tajua, miksi Youtube on täyttynyt vaimonsa hakkaajaa ja kaksoismurhaajaa, Chris Benoitia, ihannoivista videoista. Kaveri kun oli perseestä, oli hänen roolinsa pellepainissa kuinka puhtoinen hyvänsä. Etenkin lasten tappajat pitäisi mielestäni tuhkata kaikessa hiljaisuudessa ja vetää vessanpöntöstä alas kuten kaikelle muullekin paskalle tehdään.

Noin. Tulipa sanottua.

Lisää kommentti Kesäkuu 30th, 2007

Buffalot vastaan leijonat

Hillittömin video, mitä olen vähään aikaan nähnyt:

Lisää kommentti Kesäkuu 29th, 2007

Suomessa kaikki hyvin

Taas saa olla ylpeä suomalaisuudestaan. Suomi pärjäsi Foreign Policy-lehden ja Fund for Peace-säätiön The Failed States Index-tutkimuksessa erinomaisesti. Sen sijaan perheellemme tärkeistä maista Etiopia ja Sri Lanka pärjäsivät erittäin huonosti:

The Failed States Index 2007

Lisää kommentti Kesäkuu 22nd, 2007

IBM Installation Manager

Vihdoinkin IBM on kehittänyt helppokäyttöisen päivitys- ja asennusohjelman. Ikävä kyllä sitä taidetaan toistaiseksi käyttää ainoastaan RADin päivityksiin.

Esimerkiksi WebSphere Portal-palvelimen päivityksiin tämä ohjelma olisi järjetön parannus. Nykyisellään portaalin päivitys vie tuhottoman paljon aikaa kun jokainen komponentti pitää päivittää erikseen: Java SDK, Application Server, Process Server, Portal Server, IWWCM, jne, jne. Lisäksi päivityksiä tulee sellaista tahtia, että pelkästään kaikkien komponenttien versiotasot kertovat kaksi skriptiä sylkevät kumpainenkin ulos megan paketin tekstiä.

IBM Installation Manager

Lisää kommentti Kesäkuu 7th, 2007

Uudemmat kirjoitukset Aikaisemmat kirjoitukset


Aiheet

Linkit

Sivusto

The world is a dangerous place to live; not because of the people who are evil, but because of the people who don't do anything about it.
- Albert Einstein