Po pierwsze, duże skupiska if/else
bloków nie są łatwe do przetestowania . Każda nowa „gałąź” dodaje inną ścieżkę wykonania, a tym samym zwiększa złożoność cykliczną . Jeśli chcesz dokładnie przetestować swój kod, musisz pokryć wszystkie ścieżki wykonania, a każdy warunek wymagałby napisania co najmniej jednego testu (zakładając, że piszesz małe, ukierunkowane testy). Z drugiej strony klasy wdrażające strategie zazwyczaj ujawniają tylko 1 metodę publiczną, którą łatwo przetestować.
Dzięki zagnieżdżeniu if/else
skończysz wiele testów dla jednej części kodu, podczas gdy w Strategii będziesz mieć kilka testów dla każdej z wielu prostszych strategii. W tym drugim przypadku łatwiej jest uzyskać lepszy zasięg, ponieważ trudniej jest pominąć ścieżki wykonania.
Jeśli chodzi o rozszerzalność , wyobraź sobie, że piszesz platformę, w której użytkownicy powinni mieć możliwość wprowadzenia własnych zachowań. Na przykład, chcesz stworzyć pewien rodzaj ram obliczania podatków i chcesz wspierać systemy podatkowe różnych krajów. Zamiast wdrożyć je wszystkie, po prostu chcesz dać użytkownikom frameworków szansę na wdrożenie sposobu obliczania niektórych określonych podatków.
Oto wzorzec strategii:
- Na przykład definiujesz interfejs,
TaxCalculation
a twoja struktura akceptuje instancje tego typu do obliczania podatków
- Użytkownik frameworka tworzy klasę, która implementuje ten interfejs i przekazuje go do frameworka, umożliwiając w ten sposób wykonanie części obliczeń
Nie możesz zrobić tego samego if/else
, ponieważ wymagałoby to zmiany kodu frameworka, w którym to przypadku nie byłby już frameworkiem. Ponieważ frameworki są często dystrybuowane w formie skompilowanej, może to być jedyna opcja.
Mimo to, nawet jeśli piszesz zwykły kod, Strategia jest korzystna, ponieważ sprawia, że twoje zamiary stają się wyraźniejsze. Mówi „ta logika jest podłączalna i warunkowa”, tzn. Może istnieć wiele implementacji, które mogą się różnić w zależności od działań użytkownika, konfiguracji, a nawet platformy.
Stosując wzór strategia może poprawić czytelność , ponieważ, podczas gdy klasa który realizuje jakąś szczególną strategię zazwyczaj powinien mieć nazwę opisową, na przykład USAIncomeTaxCalculator
, if/else
bloki są „bezimienny”, w najlepszym przypadku tylko komentuje i komentarze mogą kłamać. Ponadto, według mojego osobistego gustu, posiadanie więcej niż 3 if/else
bloków z rzędu jest nieczytelne i robi się całkiem źle z zagnieżdżonymi blokami.
Zasada Otwarta / Zamknięta jest również bardzo istotna, ponieważ, jak opisałem w powyższym przykładzie, Strategia pozwala rozszerzyć logikę w niektórych częściach twojego kodu („otwarta na rozszerzenie”) bez przepisywania tych części („zamknięta dla modyfikacji” ).