Rozumiem intencję zasady otwartego zamknięcia. Ma to na celu zmniejszenie ryzyka zepsucia czegoś, co już działa, podczas modyfikowania go, poprzez nakazanie próby rozszerzenia bez modyfikacji.
Miałem jednak pewne problemy ze zrozumieniem, w jaki sposób ta zasada jest stosowana w praktyce. W moim rozumieniu istnieją dwa sposoby zastosowania tego. Przed i po możliwej zmianie:
Przedtem: programuj abstrakcje i „przewiduj przyszłość” tak bardzo, jak potrafisz. Na przykład metoda
drive(Car car)
będzie musiała ulec zmianie, jeśliMotorcycle
s zostaną dodane do systemu w przyszłości, więc prawdopodobnie narusza OCP. Jednak metodadrive(MotorVehicle vehicle)
ta prawdopodobnie nie będzie musiała ulec zmianie w przyszłości, więc jest zgodna z OCP.Jednak dość trudno jest przewidzieć przyszłość i wiedzieć z wyprzedzeniem, jakie zmiany zostaną wprowadzone w systemie.
Po: gdy potrzebna jest zmiana, rozszerz klasę zamiast modyfikować jej bieżący kod.
Ćwiczenie nr 1 nie jest trudne do zrozumienia. Jednak jest to praktyka nr 2, że mam problem ze zrozumieniem, jak się zgłosić.
Na przykład (wziąłem go z video na YouTube): powiedzmy, że mamy metodę w klasie, który akceptuje CreditCard
obiekty: makePayment(CraditCard card)
. Jeden dzień Voucher
są dodawane do systemu. Ta metoda ich nie obsługuje, więc należy go zmodyfikować.
Wdrażając metodę, nie udało nam się przewidzieć przyszłości i program w bardziej abstrakcyjny sposób (np. makePayment(Payment pay)
Teraz musimy zmienić istniejący kod.
Ćwiczenie nr 2 mówi, że powinniśmy dodać tę funkcjonalność, rozszerzając zamiast modyfikować. Co to znaczy? Czy powinienem podklasować istniejącą klasę zamiast po prostu zmieniać jej istniejący kod? Czy powinienem zrobić wokół niego jakieś opakowanie, aby uniknąć przepisywania kodu?
Czy też zasada nie odnosi się nawet do „jak poprawnie zmodyfikować / dodać funkcjonalność”, ale raczej do „jak uniknąć konieczności wprowadzania zmian w pierwszej kolejności (tj. Programu do abstrakcji)?