Devloger

Refaktoryzacja Kodu Strategiami

Refaktoryzacja Strategiami

Obraz logo refaktoryzacji kodu strategiami

Kolejny sposób na refaktoryzację kodu. Bardzo zmyślny i elegancki, polimorficzny Emotikon uśmiechniętej buźki. Jeden cel - wiele sposobów/strategii/algorytmów/dróg...

Na czym on polega?

Metoda ta polega na rozdzieleniu różnych algorytmów, których zadaniem jest osiągnięcie ogólnie jednego i tego samego celu (pewien wspólny cel). Zamiast sprawdzać okoliczności stosując warunki (instrukcje warunkowe if) a następnie wykonując pewne działania - to zamykamy te działania w osobnych klasach (klasy strategii, strategie) a okoliczności raz sprawdzane (przez metodę lub klasę za to odpowiedzialną) zadecydują o adekwatnej strategii.

Zazwyczaj zamiast tej metody stosuje się proste i szybkie sprawdzenia (ify). Sprawdzamy przeróżne okoliczności od których zależy co nastąpi dalej. Jednak łamie to wiele zasad i dobrych praktyk, nie jest skalowalne a jest wręcz nieeleganckie i niechlujne. Prowadzi do zepsucia i trudnościach w utrzymaniu kodu.

Kiedy skorzystać z tej techniki refaktoryzacji?

Sprawdza się to szczególnie w sytuacji, kiedy możesz daną rzecz wykonać na wiele różnych sposobów. Kiedy masz wiele strategii, algorytmów, dróg, działań, reakcji... A jaką należy wybrać? To zależy... Wówczas ta metoda sprawdza się idealnie Emotikon uśmiechniętej buźki.

Na te różne sposoby by dojść do pewnego celu patrz jak na strategie Emotikon uśmiechniętej buźki. To są strategie, które możesz uskutecznić by wykonać jakieś konkretne działanie. Działanie jest jedno, ale sposób jego osiągnięcia różny i zależny od wielu czynników. Każda strategia doprowadzi cię do tego samego celu, ale one wszystkie są unikatowe.

Jak zastosować tę metodę?

Po pierwsze znajdź punkt elastyczności. Znajdź takie miejsce w kodzie, gdzie możesz być elastyczny co do tego jak dojdziesz do konkretnego miejsca, sposób, algorytm, strategia. Punkt w którym możesz tego dokonać na wiele sposobów, masz wiele dróg.

Po drugie wyodrębnij każdą strategię do dedykowanej klasy.

Po trzecie upewnij się, że każda z tych strategii (klas) należy do wspólnego API/kontraktu/interfejsu. A oznacza to tyle, by po prostu upewnić się, że wszystkie te strategie (klasy) posiadają metodę o tej samej nazwie (wspólna metoda). Pozwoli nam to, na wykorzystanie mocy polimorfizmu Emotikon uśmiechniętej buźki.

To czy stworzysz ten interfejs - faktycznie - i zobowiążesz owe klasy strategii do jego implementacji - zależy wyłącznie od ciebie i jest opcjonalne. Nie musisz tego robić, ale jeśli uważasz że to ma sens, masz tak wiele przeróżnych strategii i uważasz, że da ci to dużo dobrego i jest użyteczne - wtedy zrób to Emotikon uśmiechniętej buźki. W przeciwnym razie, jeśli strategii masz tylko kilka... Czy naprawdę potrzebujesz tego interfejsu? Ponieważ to nie ma tak naprawdę znaczenia. A warto utrzymywać wszystko w prostocie (KISS) Emotikon uśmiechniętej buźki. Jeśli tego nie zrobisz nie czyni to z ciebie złego programisty czy architekta oprogramowania, ani trochę. To czy warto mieć ten interfejs czy nie - zależy od kontekstu Emotikon uśmiechniętej buźki.

Po czwarte określ adekwatną strategię i pozwól jej zająć się zadaniem Emotikon uśmiechniętej buźki.

Dodatkowe informacje

Tworząc klasę strategii nazywaj ją adekwatnie do tego co ona robi, jakie jest jej zadanie. Dla przykładu RegistersLifetimeUser.

Klasy strategii dzielą wspólne API, więc bez względu na to którą strategię wybierzesz, możesz wywołać tę samą metodę. Wszystko dzięki polimorfizmowi.

Często by osądzić w kodzie która droga jest adekwatna w obecnej sytuacji wykorzystać można metodę lub klasę fabryki (factory method / factory class). I to ta klasa/metoda będzie odpowiedzialna za wyznaczenie adekwatnej drogi/algorytmu/strategii. To będzie jej odpowiedzialnością, a gdy już ją wyznaczy - wystarczy że ją stworzy i zwróci.

Gdy wiemy już którą strategię chcemy wykonać... wystarczy ją wykonać Emotikon uśmiechniętej buźki (wykorzystując wspólną metodę, interfejs).

Przykład

Rejestracja użytkownika. Cel jeden, ale dróg i sposobów na to może być wiele. Ponieważ możemy rejestrować zwykłego użytkownika, płatnego, vip i tak dalej... W poniższym przykładzie - regularnego użytkownika i użytkownika z wiecznym dostępem do treści.

<?php
// strategia rejestracji użytkownika z wiecznym dostępem do treści
class RegistersLifetimeMember {
    public function handle() {
    // pierwsza droga, rejestracja użytkownika z wiecznym dostępem do treści...
    }
}

// strategia rejestracji regularnego użytkownika
class RegistersUser {
    public function handle() {
    // druga droga, rejestracja regularnego użytkownika...
    }
}

// kontroler subskrypcji
class SubscriptionsController
{
    // metoda odpowiedzialna za rejestrację użytkownika
    public function store(Request $request)
    {
        // wybierz odpowiednią strategię i wykonaj ją
        $this->getRegistrationStrategy($request)->handle(); // piękna potęga polimorfizmu Emotikon uśmiechniętej buźki
    }

    // metoda odpowiedzialna za wybranie adekwatnej strategii (factory method)
    protected function getRegistrationStrategy(Request $request)
    {
        // wybieranie adekwatnej strategii w zależności od pewnych okoliczności...
        if($request->plan == 'forever') {
            // wybieram strategię rejestracji użytkownika z wiecznym dostępem do treści...
            return new RegistersLifetimeMember;
        }
        // wybieram strategię rejestracji regularnego użytkownika
        return new RegistersUser;
    }
}

Zalety

Cała logika związana ze wszystkimi strategiami nie leży już w jednym miejscu (nieodpowiednim do tego), przygnieciona stertą zbędnych warunków i innym kodem. Teraz każda strategia ma swoją własną, dedykowaną klasę Emotikon uśmiechniętej buźki. Pozbyliśmy się zbędnych warunków, zastosowaliśmy się do dobrej praktyki, świetnego wzorca i wykorzystujemy potęgę polimorfizmu. Kod jest teraz czystszy, dużo lepiej skalowalny i ma znacząco poprawioną architekturę... Po prostu, lepszy kod Emotikon uśmiechniętej buźki!

Podsumowując

Brzmi przytłaczająco? Skomplikowanie? A wcale takie nie jest Emotikon uśmiechniętej buźki. I mam nadzieję, że doszedłeś do tego samego wniosku po lekturze tego artykułu i przeanalizowaniu użytego w nim przykładu.

Pamiętaj, by określić, czy jest to technika refaktoryzacji kodu którą możesz użyć - zobacz czy możesz znaleźć punkt elastyczności w związku z wykonaniem pewnego zadania (w przykładzie z tego artykułu - jeden punkt elastyczności z dwiema strategiami). Wyodrębnij każdą strategię do osobnej klasy. W klasach tych zaimplementuj jeden wspólny interfejs. I ostatecznie użyj jakiejś fabryki (zazwyczaj metody), której zadaniem będzie wyznaczenie adekwatnej strategii a następnie jej użyj Emotikon uśmiechniętej buźki.

Potęga polimorfizmu znów w akcji Emotikon uśmiechniętej buźki. Piękna rzecz.

Kończąc

To już wszystko w temacie refaktoryzacji strategiami Emotikon uśmiechniętej buźki. Jeśli ten artykuł był dla ciebie jakkolwiek przydatny to proszę podziel się nim z innymi, udostępnij go Emotikon uśmiechniętej buźki.

Proszę cię również o zostawienie komentarza, podziel się swoją opinią o tym artykule i tym temacie.

Zapraszam cię również do lektury innych moich artykułów, szczególnie tych związanych z refaktoryzacją kodu Emotikon uśmiechniętej buźki.

A tymczasem życzę ci dobrego dnia, bywaj Emotikon uśmiechniętej buźki!

Krystian Bogucki

Podobał Ci się ten artykuł?

Jeśli tak, to zarejestruj się aby otrzymywać powiadomienia o nowych artykułach. Nie ujawnię nikomu Twojego adresu!