Skip to content

Witaj w Świecie Jutra!

  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
  • Home
  • Wszystko
  • Wzorce projektowe – Composite
  • Programowanie
  • Wszystko

Wzorce projektowe – Composite

Jakub Raczkowski 28 stycznia 2024

Źródło: https://ichef.bbci.co.uk

U wielu ludzi popularne jest powiedzenie: „zasady są po to aby je łamać”. Ja uważam, że wręcz przeciwnie. Stąpanie po kruchym lodzie, sikanie pod wiatr, świecenie latarką sobie zamiast ojcu – pewnych rzeczy nie powinno się robić i kropka. A jak to wygląda w świecie oprogramowania?

W artykule „SOLIDne programowanie” omówiłem z wami kilka ważnych reguł jak pisać kod, aby nie tylko działał ale i do czegoś się nadawał. Potem doszło jeszcze kilka porad w czasie gdy przerabialiśmy wzorce projektowe. Która z tych wszystkich zasad jest najważniejsza? Która najmniej? Którą najchętniej byście złamali?

Wszystko zależy od sytuacji – bilansu zysku i strat. Czy pracujemy nad projektem samodzielnie? Czy jest krótki czy długoterminowy? Czy płacą nam za efekt czy od godziny? I tak dalej…

Bohater dzisiejszego artykułu – wzorzec Kompozyt – łamie zasadę pojedynczej odpowiedzialności (SOLID -> S: Single Responsibility Principle), bo jednocześnie zarządza strukturą i wykonuje operacje swojej klasy.

Co dostajemy w zamian?

Kompozyt – łączy obiekty w strukturę drzewa reprezentującą hierarchię część-całość. Umożliwia klientom jednolite traktowanie pojedynczych obiektów i ich kompozycji.

Rusz głową! Wzorce projektowe

Żeby dobrze sobie zwizualizować jak działa Composite weźmy za przykład biblioteki Swing wbudowane w Javę. Pozwalają one szybko stworzyć podstawowy interfejs graficzny dla naszej aplikacji.

Swing: ramka JFrame, na niej panel JPanel i kwadraty (JComponents)

Wszystko zaczyna się od obiektu JFrame który jest naszym okienkiem gdzie będzie działać appka. Owe okienko możemy podzielić na segmenty – obiekty JPanel, a w nich umieścić komponenty (JComponent) takie jak grafiki, tekst, czy przyciski.

Jak widzicie, taki panel JPanel może być samotnym elementem, a może też zawierać całą masę różnych komponentów – czyli wspomnianą wyżej „kompozycję obiektów”. Zastosowanie wzorca Kompozyt pozwala traktować wszystkie te elementy tak samo. Jednakże aby to dobrze zrozumieć potrzebny będzie konkretny przykład.

Ale po kolei…

Odniosę się do artykułu ze wzorcem Polecenie – bo to właśnie tam opisywałem wam jak działa „sekwencer zaklęć„. W skrócie – sekwencer to zaklęcie, które samo nic nie robi, ale za to przechowuje w sobie 3 inne, które można odpalić jednocześnie. W kodzie naszego czarodzieja potrzebowaliśmy dodatkowych metod: addTosequencer() która umieszczała czary oraz fireSequencer() która je wyzwalała.

A teraz zastanówmy się – czy dałoby się to ogarnąć bez tych dodatkowych metod?

A i owszem. O tak: (pełny kod tutaj)

static class Wizard{
        Spell spell;
        void castSpell(Spell spell){
            this.spell = spell;
            System.out.print("(Czarodziej) Rzuca czar(y): ");
            spell.castSpell();
        }   

– Bez sensu! Magik dalej strzela TYLKO JEDNYM zaklęciem!

– No właśnie nie. Bo Kompozyt definiuje nam to co uznajemy za to zaklęcie – to może być pojedyncza sztuczka, ale również cała ich paleta:

static class CompositeSpell implements Spell{
        List<Spell> spells = new ArrayList<>();
        @Override
        public void castSpell() {
            for (Spell spell : spells) {
                spell.castSpell();
            }
        }
Czarodziej rzuca kompozytowe zaklęcie, które okazuje się trzema innymi.

Klasa „Czar kompozytowy” (CompositeSpell) jest JEDNOCZEŚNIE jednym czarem (implementuje interfejs Spell) i kilkoma zaklęciami (przechowywanymi w liście spells).

– Na tym właśnie polega magia wzorca Kompozyt.

– Dobra, dobra! Ale idąc dalej tym podejściem, każdy czar musi mieć te same metody! A przecież jedne atakują wroga, inne przyzywają sojuszników, dają buffy, leczą czy teleportują. One wszystkie powinny implementować inne interfejsy, a wtedy Kompozyt nie zadziała!

– Nie bój się, zadziała. Musimy tylko złamać kolejną regułę:

Nie dawaj klasom metod z których nie korzystają.

Spójrzcie na to:

Interfejs Spell zawiera metodę unsummon(), która nie jest potrzebna każdej z obsługujących go klas.

Aby Kompozyt spełniał swoją rolę wszystkie jego obiekty muszą współdzielić ten sam interfejs – nawet jeśli wydaje się to bez sensu, żeby np. „odesłać czar zamiast przyzwańca” (metoda unsummon()). Wtedy po prostu używamy wyjątku „Unsupperted Operation Exception” tam gdzie ta metoda nie ma działać. A klasę kompozytową uzbrajamy w klauzulę try-catch:

@Override
        public void unsummon() {
            for (Spell spell : spells) {
                try{
                    spell.unsummon();
                } catch (UnsupportedOperationException ignored){}
            }
        }

Powyższy algorytm po prostu ignoruje te czary, które nie mogą zostać odwołane. Nie jest to kodowanie najwyższych lotów, ale często jest to gra warta świeczki dzięki której zyskujemy na hermetyzacji.

ITCandidateEvaluator

Szczerze powiedziawszy: Sam nie wiem. Kompozyt nie należy ani do najłatwiejszych wzorców, ani do najpopularniejszych. Musi być konkretny powód, aby go zastosować (i przy okazji złamać parę zasad poprawnego programowania).

W książce „Wzorce Projektowe” Kompozyt świetnie się sprawdził przy tworzeniu menu w restauracji – dzięki zastosowaniu tego wzorca, jadłospis można było łatwo rozwijać o dodatkowe pozycje będące równocześnie osobnymi „podmenu”.

Być może znajdę miejsce dla kompozytu przy grupowaniu pytań rekrutacyjnych – jak wiadomo niektóre są krótkie i szybkie, zaś inne mogą prowadzić do całej gamy tzw. „follow-up questions” – pytań dodatkowych będących odpowiednikiem w/w podmenu. Zobaczymy.

Na dzisiaj zakończymy temat, ale widzimy się już wkrótce razem ze wzorcem „Stan„.

Tags: design patterns programming

Continue Reading

Previous: Wzorce projektowe – Iterator
Next: Wzorce projektowe – State

Related Stories

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025

Ze świata

  • Antyweb
  • Kwantowo
  • Dwóch po dwóch
Netflix odpala nową funkcję, która da użytkownikom więcej władzy
Tanie iPhone'y i Samsungi w nowym sklepie Orange
Fani Androida mają powód do radości. Wraca wsparcie uwielbianej funkcji
Wielkie nieporozumienie wokół nowego iPhone’a. Zobaczcie to, zanim zaczniecie krytykować
Chiny przejmują legendarny oddział Sony. Koniec ery
Tak chcemy wyjaśnić napięcie Hubble'a. Lepszej metody dotąd nie było
Netflix odkrywa karty o premierach. Wiemy, co pokaże na dniach
A co powiesz na ładowanie... laserem? Badacze już to testują
ChatGPT zabierze nasze pieniądze? Nowy pomysł jeszcze gorszy niż reklamy
To najmniejsza myszka na świecie. Użyjesz jej wszędzie
Ta aplikacja to „centrum dowodzenia” każdego miłośnika podróży
Kaufland zaszalał. Rozchwytywany sprzęt Parkside trafił na półki
O tych nowościach w Windows 11 jest dziwnie cicho. A szkoda
Microsoft szykuje rewolucję. Skorzystasz, jeśli obejrzysz reklamy
Te zestawy LEGO za moment znikną z rynku. Wiecie, co to oznacza?
To już ostatni dzwonek! Skorzystaj za darmo, zanim Apple to wyłączy
Masz uczulenie na sierść psa? Z tym nic ci nie grozi
Prawdziwa bomba od T-Mobile - klienci Heyah będą zachwyceni!
Garmin, Samsung i Apple na celowniku. Te zegarki mogą zniknąć z rynku
Łatwiej zmienisz przeglądarkę na iPhonie. Wystarczy jedna opcja
To by było na tyle, jeśli chodzi o możliwość ugody
Ocalić od zapomnienia
Ostatni kwant
ALH 84001 – meteoryt, o którym mówiono nawet w Białym Domu
HESS zarejestrował kosmiczny elektron o niespotykanej energii [Phys. Rev. Lett.]
Matka ciemnej materii – recenzja biografii “Vera Rubin. Życie”
Satelita, który zerwał się ze smyczy
Wiadomość od Carla Sagana do przyszłych eksploratorów Marsa
Ile najdłużej może trwać zaćmienie Słońca?
Nowa największa liczba pierwsza ma ponad 41 milionów cyfr [GIMPS]
30 lat konsoli PlayStation – Odcinek #130
Omawiamy serię The Walking Dead (gość: Stary Gracz)
Nikt nie potrzebuje cienkich smartfonów – Odcinek #129
To ostatni dzwonek na kolekcjonowanie gier i filmów
Najlepsza relacja z PGA 2025 (Poznań Game Arena)
Bumblebee wśród klawiatur. Marvo Meqa 80W – recenzja
Pierwsze spotkanie z Omoda 7 Super Hybrid
Logitech MX Master 4, Wednesday, 1670 sezon 2 – Odcinek #128
Tani pad, który chciał być jak DualSense. Test Monka Contra GT-96
Secret Service i prasa komputerowa w Polsce – Odcinek #127

To może cię zainteresować:

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025
Czym jest Swagger?
  • Programowanie

Czym jest Swagger?

22 lipca 2024
  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
Copyright © All rights reserved. | DarkNews by AF themes.