The Whole is Greater than the Sum of its Parts
-Aristotle
Ten cytat jest przypisywany Arystotelesowi. Podstawową kwestią jest synergia. W bestsellerowej książce Stephena Covey’a „7 nawyków skutecznych ludzi” szóstym nawykiem jest „Synergia”. To, co jest prawdą w przypadku organizacji, jest prawdą również w informatyce. Ciało obiektu jest bardziej wartościowe niż jego jednostka. W informatyce używamy terminu kompozycja.
Kompozycja
Co więc rozumiemy przez kompozycję? „Kompozycja jest jednym z podstawowych pojęć w programowaniu obiektowym. Opisuje klasę, która odwołuje się do jednego lub więcej obiektów innych klas w zmiennych instancji. Pozwala to na modelowanie asocjacji has-a między obiektami.” W ten sposób Stackify opisuje to tutaj. Pomyśl o tym jak o orkiestrze. Jeden wykonawca jest miły, ale kiedy masz całą grupę razem, muzyka jest bogatsza i głębsza.
Korzyści
Główną korzyścią dla kodu stworzonego z prawidłową kompozycją jest ponowne użycie. Jeśli zaprojektujesz go poprawnie, powinien być łatwy do ponownego użycia. Jeśli nie, może to być dość kłopotliwe. Wraz z tym jest intuicyjne i czyste API lub Interfejs Programowania Aplikacji. Jako doświadczony programista Java, słyszałem wiele osób ubolewających nad projektem API Javy do obsługi wątków. Dobry projekt powinien pozwolić ci zmienić coś wewnętrznie i nie zmieniać tego, jak inni z tym współdziałają.
Przykłady
Stwórzmy przykład, abyśmy mogli zobaczyć, jak wygląda kompozycja w Javie.
Tutaj mamy zdefiniowaną naszą klasę Role.
Klasa Role jest używana w klasie Employee. W kompozycji powiedzielibyśmy, że klasa Employee „has-a” Role.
Hiding
W naszym przykładzie API, klasy HotDogGrinder i HotDogGrill są pakietami prywatnymi i nie można się do nich dostać z zewnątrz.
Tutaj jest publiczna twarz naszego API, HotDogMachine. Ta klasa ma odniesienie do dwóch wewnętrznych klas, które ukrywamy za pomocą naszego projektu API.
Kompozycja vs Dziedziczenie
Kompozycja i dziedziczenie mogą być mylone przez programistów. Jak wskazuje Steven Lowe w tym wpisie na blogu ThoughtWorks, musimy uważnie wybrać, którego z nich użyć.
Podziela on często słyszaną zasadę kciuka, „faworyzuj kompozycję nad dziedziczeniem”. Jak z każdą regułą kciuka musimy zrozumieć, że nie zawsze ma ona zastosowanie. Więc załatwmy kilka spraw zanim pójdziemy dalej.
Zdefiniujmy dziedziczenie, ponieważ już mówiliśmy o kompozycji na długość. Dziedziczenie jest jednym z fundamentów programowania zorientowanego obiektowo. Na przykład, jeśli mamy klasę food, to klasa bread dziedziczy po klasie food. Natomiast kompozycja zajmuje się elementami, które są częścią większej jednostki.
Lowe przypomina nam, że kiedy moglibyśmy użyć któregoś z nich, musimy zadać dwa różne pytania. Po pierwsze, „Reprezentacja / implementacja twoich koncepcji domeny jest jednym wymiarem”. Zasadniczo, jeśli oba są w tej samej domenie dziedziczenie jest prawdopodobnie twoim najlepszym zakładem. Po drugie, „Semantyka twoich pojęć domeny i ich relacji między sobą jest drugim wymiarem”. Komponenty, które tworzysz, zaczynają przekazywać do innego to może być znak, że możesz potrzebować ponownie rozważyć użycie dziedziczenia zamiast.
Kompozycja jest wielką zasadą w rozwoju oprogramowania, że wielu z nas profesjonalistów bałagan. Sam to robiłem tworząc rozwiązania, które nie podchodziły do tego poprawnie. Szybka dyskusja na tablicy z kolegą lub naszkicowanie czegoś na kartce papieru może pomóc ci zrozumieć, kiedy istnieje relacja „has-a” pomiędzy dwoma obiektami. Po przeczytaniu tego powinieneś również zrozumieć korzyści i wiedzieć, jak użyć tego w przykładzie. Spróbuj zbudować jakiś przykład i użyć go, wtedy powinieneś wiedzieć, czy jesteś na dobrej drodze, czy może dziedziczenie może być lepszą ścieżką.