Pokazywanie postów oznaczonych etykietą GRASP. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą GRASP. Pokaż wszystkie posty

poniedziałek, 4 sierpnia 2008

Strategia na wielokrotne dziedziczenie

Wielokrotne dziedziczenie jest be - wszyscy o tym wiemy. Poza oczywistymi problemami logicznymi narusza jedną z głównych zasad OO - utrzymywanie wysokiej kohezji - klasa powinna mieć jak najmniej odpowiedzialności, najlepiej jedną.

Ostatnio zmagałem się z zaprojektowaniem pewnego modelu dostarczonego z fazy analizy. Model analityczny był w sumie dosyć prosty, jednak kobieca intuicja podpowiadała, że będzie sprawiał problemy z rozbudową w przyszłości. Problem domenowy wyglądał tak: mamy zlecenie podania leku; zakładamy, że w przyszłości na pewno dojdą do wykonania inne rzeczy; możemy również zlecać wykonanie czegoś raz lub wielokrotnie (okresowo, wg zadanego wzorca powtarzania).

Model analityczny wyglądał tak: mamy zlecenie, po którym dziedziczy zleceniePodaniaLeku, po którym to z kolei dziedziczą zlecenia jednorazowegoPodaniaLeku jak i wielokrotnegoPodaniaLeku. Czujecie chyba eksplozję kombinatoryczną, która się szykuje w razie pojawienie się nowych rodzajów rzeczy do zlecenia czy nowych polityk powtarzania, lub (o zgrozo) pojawienie się nowych aspektów zlecenia.

Widać tu jak na dłoni wzorzec projektowy Strategii. Postępując zgodnie z tym wzorcem dojdziemy do modelu, gdzie zlecenie składa się ze strategii powtarzania - lub polityki idąc za terminologią Domain Driven. Zlecenie składa się też ze strategii wykonania pewnej czynności. Zlecenie "widzi" jedynie interfejsy strategii, natomiast z jego punktu widzenia implementacje nie są istotne.
Podejście to zapewni nam również zgodność z kolejną zasadą GRASP.

Wzorzec co prawda "widać" z perspektywy projektowej czy implementacyjnej, jednak z perspektywy analitycznej ponoć wygodniej jest pokazać wielodziedziczenie - po typie powtarzania i po typie czynności do wykonania. Jednak ponieważ wielodziedziczenie jest be, więc aby go uniknąć doszło na poziomie analizy do "rzutowania" aspektu powtarzania na aspekt czynności.

Sytuacja z dystansu wygląda śmiesznie: analitycy "szyfrują" rzeczywistość do jednowymiarowej przestrzeni aby uniknąć wielodziedziczenia, a projektanci muszą później dokonać "odszyfrowania" na swoje strategie;)

Dlatego też wspólnie uznaliśmy, że wielodziedziczenie jest git - ale tylko na poziomie analitycznym:P Dzięki niemu projektanci mogą niemal w sposób automatyczny dokonać transformacji modelu analitycznego na implementacyjny model obiektowy oparty na strategiach. Niemal automatyczny ponieważ wszystkie wielowymiarowe aspekty dokładnie "widać" gdy nie są spłaszczone do jednego wymiaru


//===========================
Tak właściwie to nie jestem do końca przekonany czy aby na pewno wielodziedziczenie jest immanentną cechą obiektów ze świata rzeczywistego. Być może jest to jedynie kwestia wyuczonego postrzegania; wynik bezkrytycznego powielania schematów myślowych. Pamiętam, że sam zanim przestawiłem się na agregację/kompozycję, widziałem wszędzie dziedziczenie - wszak kto ma w ręku młotek, ten wszędzie widzi gwoździe.

GRASP jest doskonale opisany w "Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development" autorstwa Craiga Larmana