Zasada otwartego zamknięcia (OCP) stanowi, że obiekt powinien być otwarty do rozszerzenia, ale zamknięty do modyfikacji. Wierzę, że rozumiem to i używam go w połączeniu z SRP do tworzenia klas, które robią tylko jedną rzecz. I staram się stworzyć wiele małych metod, które umożliwiają wyodrębnienie wszystkich elementów sterujących zachowania na metody, które mogą być rozszerzone lub zastąpione w niektórych podklasach. Tak więc kończę na klasach, które mają wiele punktów rozszerzenia, czy to poprzez: wstrzykiwanie zależności i skład, zdarzenia, delegowanie itp.
Rozważ następujące proste, rozszerzalne klasy:
class PaycheckCalculator {
// ...
protected decimal GetOvertimeFactor() { return 2.0M; }
}
Teraz powiedzmy na przykład, że OvertimeFactorzmiany na 1.5. Ponieważ powyższa klasa została zaprojektowana z myślą o rozszerzeniu, mogę łatwo podklasę i zwrócić inną OvertimeFactor.
Ale ... pomimo tego, że klasa została zaprojektowana do rozszerzenia i przestrzegania OCP, zmodyfikuję pojedynczą metodę, o której mowa, zamiast podklasować i zastępować tę metodę, a następnie ponownie okablować moje obiekty w moim kontenerze IoC.
W rezultacie naruszyłem część tego, co OCP próbuje osiągnąć. Mam wrażenie, że jestem po prostu leniwy, ponieważ powyższe jest nieco łatwiejsze. Czy źle zrozumiałem OCP? Czy naprawdę powinienem robić coś innego? Czy w inny sposób wykorzystujesz zalety OCP?
Aktualizacja : w oparciu o odpowiedzi wygląda na to, że ten wymyślony przykład jest kiepski z wielu różnych powodów. Głównym celem tego przykładu było wykazanie, że klasa została zaprojektowana w taki sposób, aby była rozszerzana poprzez dostarczenie metod, które w przypadku zastąpienia zmieniłyby zachowanie metod publicznych bez potrzeby zmiany kodu wewnętrznego lub prywatnego. Mimo to zdecydowanie źle zrozumiałem OCP.