Written by 21:12 Dobre praktyki

Zasada Open/Close. SOLID

Zasada Open/Close– Zdefiniowana przez Bertranda Meyera w 1988 roku. Wchodzi w skład SOLID. Mówi ona:

“Element oprogramowania (klasa, moduł, funkcja) powinien być otwarty na rozbudowę, ale zamknięty na modyfikacje.”

“Oznacza to, że zachowanie elementu oprogramowania powinno pozwalać na rozbudowę bez konieczności modyfikowania samego elementu.” Robert C. Martin. “Czysta architektura”

Open/Close otwarty na rozbudowę — ponieważ możemy rozszerzyć zachowanie modułu.

Zamknięty na modyfikację – ponieważ rozszerzenie zachowania modułu nie powoduje zmian w kodzie źródłowym lub binarnym modułu, ponieważ binarna wersja wykonywalna modułu, pozostaje nienaruszona.

Jest to cel idealny, do którego dążymy pisząc oprogramowanie.

Jak możemy pisać taki kod?

  • uzależniać obiekty od abstrakcji, nie od implementacji. Wykorzystywać klasy abstrakcyjne i interfejsy
  • wykorzystywać polimorfizm
  • odpowiednio korzystać z piątej zasady SOLID – zasady odwracania zależności (o tym w najbliższych mailach)
  • korzystać ze wzorców: Strategi, Dekoratora

Lepsza klasa abstrakcyjna czy interfejs w Open/Close?

Dziedziczenie wprowadza silny coupling (o tym pisaliśmy wcześniej: link do portalu tylko dla PREMIUM) – podklasy zależą od szczegółów implementacji klasy nadrzędnej. Dlatego lepiej jest korzystać z interfejsów.

Interfejs pozwala wprowadzać różne implementacje. Więc można je łatwo podmieniać bez zmiany kodu, który ich używa. Interfejsy są zamknięte na modyfikacje. Ponieważ możesz rozszerzać funkcjonalność tworząc nową implementację. Dlatego zasada zachowana.

Implementacje interfejsu są od siebie niezależne i nie wymagają udostępniania żadnego kodu. Jeśli uznasz za korzystne, aby dwie implementacje interfejsu współdzieliły jakiś kod, możesz użyć dziedziczenia lub kompozycji.

Open/Close pokażemy na przykładzie o zniżkach: link

Mamy produkty i chcemy dawać na nie zniżki, ponieważ teraz tylko mamy jedną zniżkę dla wszystkich. Poniżej obiekt tej zniżki. Ma metodę apply, która oblicza zniżkę na podstawie ceny.

W przypadku, gdy mamy do dyspozycji tylko jedną zniżkę, to jest okej.

Natomiast co jeśli, będziemy chcieli dodać zniżkę dla seniorów?

Dlatego dodajmy nową klasę SeniorDiscount.

Tutaj niestety musimy zmodyfikować nasz serwis obliczający zniżki. Dlatego łamie to naszą zasadę:

Dlatego wykorzystajmy polimorfizm, aby nasz kod spełniał zasadę Open/Close. Stwórzmy interfejs Discount:

Dodajmy implementację tego interfejsu AdultDiscount i SeniorDiscount:

Dlatego zmodyfikujmy metodę applyDiscounts, która jako argument dostanie listę zniżek, które zaaplikuje do ceny. Jak widzimy, korzystamy z abstrakcji – interfejsu.

Teraz, gdy będziemy chcieć dodać kolejną zniżkę (rozszerzyć zachowanie), to wystarczy, że dodamy kolejną implementację interfejsu Discount. Ponieważ nie modyfikujemy istniejących elementów. Nie modyfikujemy DiscountService jak to było wcześniej bez wykorzystania polimorfizmu.

Ważne:
  • całkowite spełnienie tej zasady jest niemożliwe
  • wykorzystuj abstrakcje tylko tam, gdzie prawdopodobne będą zmiany
  • poczekaj na nowe wymaganie, a następnie dokonaj refaktoryzacji, aby zabezpieczyć się przed takimi zmianami w przyszłości

Ponieważ w przeciwnym razie może to spowodować niepotrzebną złożoność!

 
Źródła:

https://dzone.com/articles/solid-principles-openclosed-principle

https://howtodoinjava.com/design-patterns/open-closed-principle/

Tagi: Last modified: 7 stycznia 2022
Close

PRAKTYCZNE WSKAZÓWKI Z PROGRAMOWANIA W JAVIE W PIGUŁCE

Dołącz do 1000+ programistów Java, czytających praktyczne maile o dobrych praktykach programowania, architekturze mikroserwisowej i gorących newsach (1 raz w tygodniu)

Praktyczna Java

Swój Pakiet Powitalny Wypchany Mięsem Dostaniesz Już Za 15 Minut.

Uzupełnienie powyższego pola stanowi zgodę na otrzymywanie od Kamila Michno newslettera zawierającego treści informacyjnych, marketingowych dotyczących portalu praktycznajava.pl. Zgodę można wycofać w każdym czasie. Wycofanie zgody nie ma wpływu na zgodność z prawem przetwarzania dokonanego przed jej wycofaniem.