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
Elon Musk zamówił LEGO i uruchomił lawinę złośliwości. Nie wierzcie mu na słowo
Oto tatuaż, który można włączyć i wyłączyć. Badacze stworzyli niemożliwe?
iPhone 18 Pro ma coś, czego wcześniej nie miał żaden iPhone
Używasz starej karty SD? To duży błąd
To jeden z największych problemów komputerów kwantowych. Jesteśmy krok bliżej przełomu
Pierwszy, poważny dowód na nieznaną planetę Układu Słonecznego? Oto on
Wegetarianie kontra mięsożercy. Badanie rozstrzyga kto łatwiej zbuduje mięśnie
Garmin Fenix 9 Pro na cenzurowanym. Deweloperzy narzekają na błędy
Darmowy upgrade telewizora. Włącz te 3 ustawienia
To może być największy serial sci-fi tego roku. Blade Runner 2099 coraz bliżej
LEGO szykuje prawdziwe perełki na 2027 rok. Niektóre mogą kosztować fortunę
Microsoft ubija kolejną funkcję znanej aplikacji
Parkside pomoże ogarnąć ogród i taras. Ceny zaczynają się od 24,99 zł
GTA VI to wisienka na torcie. Jesień na Xbox to wysyp innych hitów
Głośnik jak karton mleka. Takiej nietuzinkowej technologii nam trzeba
Prawdziwy wysyp hitów na PS5. Ta jesień przejdzie do historii
Przyspiesz Windows 11 bez pobierania żadnych apek
Użytkownicy Windowsa popełniają duży błąd. Ekspert tłumaczy zły nawyk
PKO BP odcina klientów od aplikacji. I to w środku tygodnia
Twój telewizor jest za jasny. Oto dlaczego powinieneś to naprawić
IceCube – miliard ton lodu, żeby dorwać neutrino
O powstawaniu kamieni drogą doboru naturalnego
Świat upomina się o „właściwe” proporcje
Kosmiczna panorama i superkoronograf – co przyniesie nam Teleskop Nancy Roman?
O czym szepczą między sobą bozony Higgsa?
Wszechświat w trzech aktach – recenzja książki “Astronomia, kosmologia i astronautyka”
Wielka przerwa Wielkiego Zderzacza
A gdyby tak przeciąć foton na pół?
SpudCell – syntetyczna komórka, która udaje życie
Mega upał, omega manipulacja
Wyglądają i grają jak premium, a kosztują ułamek tej ceny. Recenzja Baseus Inspire XH1
W co grać W PAŹDZIERNIKU? Nowe Star Wars Racer, powrót Gears of War
Team Xbox, team OLED i nowe Avengersy – Odcinek #138
WRZESIEŃ BĘDZIE MOCNY… Premiery gier, na które czekamy – Mamy do pogrania
Całkiem dobry film ten nowy Spider-Man: Brand New Day 🕷️ – No Movie Ci #18
Scyzorykon 2026, Galaxy Fold8 i całkiem nowy Spider-Man – Odcinek #137
Sprawdziliśmy Scyzorykon 2026 od środka!
Co się działo na Fantasy & Magic Con w Warszawie?
Porozmawiajmy o Steam Machine 🎮👀
Przedsprzedaż GTA VI, Stargate i gry, które paliły sprzęty – Odcinek #136

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.