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 – Abstract factory & Factory method
  • Programowanie
  • Wszystko

Wzorce projektowe – Abstract factory & Factory method

Jakub Raczkowski 20 stycznia 2024

Bing AI

Dzisiejszy odcinek jest sponsorowany przez Hermetyzacja z.o.o. Dołącz do naszej idei, a już nigdy nie będziesz musiał mieć jakiejkolwiek styczności z innymi klasami w realu! Po co brudzić sobie ręce produkcją obiektów skoro możesz to zlecić naszym fabrykom?

Wniosek płynący z opisu wzorca Dekorator w poprzednim wpisie mógłby brzmieć następująco:

Dziedziczenie jest be, interfejsy są cacy.

Coś w tym jest, ale nie popadajmy w przesadę. O ile sztywna struktura klasowa może się okazać problemem przy późniejszej rozbudowie aplikacji, o tyle w schludny sposób deklaruje hierarchię klas i upraszcza kod. Mimo to pisząc super- i podklasy warto zadbać o wspomnianą we wstępniaku hermetyzację czyli odseparowanie elementów mających tendencję do zmian od reszty kodu.

Ale po czym poznamy takie elementy? Cóż, jedną z wskazówek może być słówko:

new

W programowaniu obiektowym musimy tworzyć nowe obiekty, to fakt. Abstrakcja klas i interfejsów pomaga w ułożeniu dobrze działającej struktury, ale koniec końców musimy i tak stworzyć jakiś obiekt, nadać mu pożądany stan i wywołać jego metody. Tylko, że można to zrobić na rympał, a można to zrobić z głową – z pomocą fabryki.

Kadr z filmu „Shrek 2”.

Tym razem zajmiemy się jednocześnie dwoma wzorcami, które stoją blisko siebie, zazwyczaj są używane razem i jednocześnie tak często są ze sobą mylone, że grzechem byłoby je rozdzielać na dwa artykuły. A są to:

Abstract Factory oraz Factory Method

Dwa wzorce z fabryką w nazwie. Znaczy – muszą coś produkować. A co? Spytajmy podręcznik:

Wzorzec Metoda Fabrykująca definiuje interfejs pozwalający na tworzenie obiektów, ale pozwala klasom podrzędnym decydować, jakiej klasy obiekt zostanie utworzony. Wzorzec MF przekazuje odpowiedzialność za tworzenie obiektów do klas podrzędnych.

Wzorzec Fabryka Abstrakcyjna dostarcza interfejs do tworzenia całych rodzin spokrewnionych lub zależnych od siebie obiektów bez konieczności określania ich klas rzeczywistych.

Rusz Głową! Wzorce projektowe.

W moim pierwszym projekcie stworzyłem klasę SquareFactory posiadającą jedną statyczną metodę createColoredSquares(…) która tworzyła dla mnie listę z żądaną ilością kwadracików w wybranym kolorze:

public static List<Square> createColoredSquares(int amount, SquareColor color) {
        List<Square> coloredSquares = new ArrayList<>();
        for (int i = 0; i < amount; i++) {
            String name = color.name().toLowerCase() + i;
            Square square = new Square(color, name);
            coloredSquares.add(square);
        }
        return coloredSquares;
    }

Nie był to jednakże przykład wykorzystania ani Factory Method ani Abstract Factory, a co najwyżej idiom czyli taki mini wzorzec, który może ograniczać się do jednej linijki kodu, która już na pierwszy rzut oka jest zrozumiała. Do pełnego wzorca trochę zabrakło.

Ale po kolei…

Jedną z najbardziej skutecznych, a jednocześnie najłatwiejszych taktyk w grach na silniku Infinity Engine (czyli takich jak Wrota Baldura albo Icewind Dale) jest przywoływanie stworzeń, tzw. „summonów” aby walczyły za nas.

Kluczem jest posiadanie w drużynie klas, które mają czar przyzwania – takich jak np. czarodziej, kleryk albo druid. Wtedy w zależności od tym kim kierujemy, możemy liczyć na powiększenie naszej drużyny o kilka wilków, żywiołaka ognia albo – na najwyższych poziomach profesji – o najprawdziwszego anioła („Devę”)!

Deva

Maksymalna ilość summonów jednocześnie to 5. Niektóre czary przyzywają od razu kilku słabszych pomagierów, z kolei inne skupiają się na przywołaniu jednego, ale za to kozaka. Mając całą piątkę takich jednorazowych minionów wysyłamy ich w rejon mapki gdzie wcześniej zauważyliśmy wrogów i czekamy patrząc na logi w dzienniku. Summony, tak jak wrogowie, mają swoje skrypty więc nie musimy im wydawać żadnych rozkazów – atakują najbliższego wroga póki nie padnie, albo same nie zginą. Kiedy akcja zelżeje wpadamy na pobojowisko swoją drużyną, likwidujemy niedobiktów i zbieramy fanty.

Klimatyczne? W żadnym wypadku!
Skuteczne? Jeszcze jak!

A teraz pomyślmy – jak najlepiej tworzyć obiekty summonów mając na uwadze, że zależą one od klasy postaci i jej poziomu oraz użytego zaklęcia? A do tego są to elementy jednorazowe, bez znaczenia dla fabuły.

Tego się nie tyka, to zrobiła fabryka.

Należy posłużyć się fabrykami, które odseparują takie szybkie tworzenie obiektów (gdzie liczy się ilość, a nie jakość) od reszty kodu. Spójrzcie poniżej, cały kod znajdziecie tutaj.

Druid przyzywa 3 wilki, a czarodziej jednego żywiołaka.
„Summoner” to prosty interfejs z jedną metodą. Bez znaczenia dla dzisiejszej lekcji.

Mamy dwie klasy: Wizard oraz Druid, z tym samym interfejsem: Summoner. Nie tworzyłem tutaj osobnych zaklęć aby nie komplikować kodu. Każda klasa korzysta z metody summon(), ale z wykorzystaniem własnej fabryki. Obie zaimplementowane fabryki są podklasami abstrakcyjnej SummonFactory (czyli naszej ABSTRACT FACTORY).

Fabryka i metoda fabryczna na jednym screenie. Zazwyczaj występują razem, ale jedna bez drugiej też może się zdarzyć.

Fabryka ta posiada dwie metody – jedna (summonAllies) jest już zaimplementowana i „dzieci” klasy używają jej dokładnie w takiej formie, bez przesłaniania. Natomiast druga (createSummons) jest abstrakcyjna i to od podklas zależy co tam dokładnie się znajdzie.

Podklasy fabryki, dla czarodzieja i druida, implementują własne wersje metody fabrycznej.

Podsumowując. Abstract factory (AF) zajmuje się tworzeniem rodziny spokrewnionych obiektów – otrzymujemy listę „summons” tylko z obiektami implementującymi owy interfejs. Factory method (FM) to pusta metoda w tej fabryce – to od podklas zależy w jaki sposób zostanie zaimplementowana.

Powyższy opis wciąż może wydawać się niejasny, dlatego poratuję was jeszcze hintem:

AF musi odpowiadać na pytanie „ile obiektów dostaniemy?”, natomiast FM na „jakie dokładnie to będą obiekty?”.

W przytoczonym kodzie AF mówi, że dostaniemy listę z iluśtam przyzwańcami. A FM tłumaczy, że jeśli jesteśmy czarodziejem to dostaniemy żywiołaka, a jak druidem to wilki.

Przy okazji – przytoczony problem równie dobrze dałoby się rozwiązać wzorcem Strategia i tak ja to właśnie zrobiłem w swoim projekcie. Jak się teraz okazuje – trochę na opak, bo zgodnie z zasadą Strategia proponuje różne algorytmy do otrzymania konkretnych danych, a wzorce Fabryki specjalizują się w tworzeniu obiektów. Niby detal, ale wiele mówi innym programistom co się dzieje w danych klasach już na pierwszy rzut oka.

ITCandidateEvaluator

Abstract factory oraz Factory method przydają się szczególnie kiedy masowo tworzymy obiekty – czy to podczas kompilacji czy już w czasie działania programu. W moim przypadku pasuje do tego szablonu obiekt „KandydatDoPracy” (Candidate). Zakładając, że na daną ofertę dostaniemy ponad 100 zgłoszeń, z czego sporo odpadnie już na etapie przeglądania CV to i tak można liczyć na kilkanaście rozmów rekrutacyjnych co przekłada się na taką samą liczbę obiektów Candidate.

Sam obiekt kandydata nie będzie szczególnie skomplikowany. Na pewno musi mieć zmienne takie jak: imię i nazwisko, może jeszcze datę urodzenia. Przyda się ścieżka do pliku z CV. Ponadto mapa „punkty” z punktami otrzymanymi na każdym etapie rekrutacji oraz metoda calculatePoints() zawierająca algorytm wyliczający końcowy wynik.

I tu właśnie zaczynają się schody. No bo tak, mogę po prostu stworzyć klasę Candidate, ustawić wszystko na sztywno i mieć resztę w du… Ale potem może się okazać, że algorytm liczący punktację dla juniora może się różnić od tego dla seniora. I zmieniaj chłopie teraz te wszystkie przypadki użycia obiektu Candidate… Lepiej niech Candidate to będzie klasa abstrakcyjna po której dziedziczą Juniorzy, Midzi i Seniorzy. Albo nie, bo może kiedyś…

Sami widzicie – sprawę należy przemyśleć bardzo dokładnie. Jedno jest natomiast pewne:

Projekt jest rozwojowy, zadbam więc o odpowiednią hermetyzację, a to oznacza, że miejsce dla jakiejś fabryki na pewno się znajdzie.

Dziękuję za uwagę i zapraszam do następnego wpisu poświęconego wzorcowi Singleton.

Tags: design patterns programming

Continue Reading

Previous: Wzorce projektowe – Decorator
Next: Wzorce projektowe – Singleton

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
Fani Sony mogą sobie teraz pozwolić na więcej z tym wyjątkowym akcesorium
Microsoft chce upodobnić Windows do macOS. Absolutna petarda!
Znaleziono drugą Ziemię. Trochę na niej chłodno
Apple AirTag 2 w praktyce. Niby taki sami, a jednak inny niż jedynka
Właściciele smartfonów Pixel zrobieni w balona. Nie tak miało być...
Zgubiłeś dowód lub paszport? mObywatel przychodzi z pomocą!
Google obiecuje, że rewolucja w komunikacji trafi na kolejne telefony
Android Auto będzie miało poważną konkurencję? CarPlay się zbroi
Nowy szef NASA mówi dość! Pora na wojnę z biurokracją
Lubisz Minecrafta? Tej oferty nie można przegapić
To nie mogło się udać. Najgorsze przykłady rebrandingu
Legalna praca zdalna: gdzie szukać ofert i jak nie dać się oszukać?
Masz światłowód Orange? Możesz płacić mniej. Dwa warunki
Disney+ ma kłopoty. Użytkownicy już zauważyli, że coś się zmieniło
3 potężne nowości na Spotify. Będziecie ich używać codziennie
Nvidia świętuje sukces. To już sześć lat rosnącej popularności
Co nowego w Windows w 2026 roku? Jest na co czekać
Spotify chce zmienić jak słuchasz piosenek. Testy już trwają
Apple się przeliczyło i zmienia plany. To dobra wiadomość dla użytkowników
HBO szykuje epickie fantasy. Czy adaptacja kultowej gry komputerowej powtórzy sukces GoT?
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.