SOLID - OCP - Reguła Otwarte-Zamknięte
OCP (Open/Closed Principle) - Bardzo prosta zasada który mówi, iż klasy powinny być otwarte na rozszerzanie lecz zamknięte na modyfikację .
Najczęściej w wyniku jej łamania dochodzi do sytuacji, w której często wracamy do jakiejś klasy i ją zmieniamy/modyfikujemy.
A dokładniej?
Otwartość klasy na rozszerzanie można też rozumieć jako możliwość zmiany jej zachowania w prosty sposób.
Natomiast jej zamknięcie na modyfikację to coś, do czego powinniśmy dążyć. Nie jest to proste, ale jest to pewnego rodzaju osiągnięcie w kontekście danej klasy.
Co to znaczy?
W tej zasadzie chodzi oto, by mieć możliwość zmiany zachowania danej klasy lecz bez modyfikacji jej oryginalnego kodu źródłowego. I tu powstaje pytanie, jak tego dokonać? I tutaj dochodzimy do tego kluczowego wyrazu - rozszerzenie.
Ale po co?
Ale powstaje też pytanie, dlaczego jest to coś do czego powinniśmy dążyć? Ponieważ będziemy w stanie zmieniać zachowanie klasy bez jej modyfikacji. Oraz unikniemy ryzyka zgnicia klasy w wyniku ciągłej jej modyfikacji (unikniemy również wielu potencjalnych bugów).
Zmiana zachowania klasy? Zamiast przez jej modyfikację to poprzez rozszerzenie!
Jak tego dokonać?
Kiedy masz moduł, który chcesz rozszerzyć bez jego modyfikacji (a tego chcemy właśnie dokonać) - rozdziel rozszerzalne zachowanie za interfejsem a następnie wymieniaj zależności.
Przy czym rozszerzalne zachowanie może być czymś co ma lub może mieć wiele różnych implementacji (strategii wykonania).
Wówczas jako że zaprogramowaliśmy to w taki sposób z wykorzystaniem interfejsu - w przypadku konieczności dokonania zmiany nie będziemy musieli modyfikować oryginalnego kodu.
I w klasie którą zamykamy na modyfikację zamiast odwoływać się do jakiejś konkretnej implementacji czy logiki (strategii) to polegamy na powszechnym interfejsie.
Klasa ta nie ma pojęcia jak dokładnie będzie to funkcjonować. I dobrze, bo nie musi. Wystarczy jej wiedza, że funkcjonalność taka istnieje i wykona swoją robotę. Tyle !
Wszystko dzięki polimorfizmowi!
Możliwości do wykazywania różnych zachowań podczas posiadania tego samego interfejsu .
Przykład
<?php
interface ShapeInterface
{
public function area();
}
class Square implements ShapeInterface
{
public $width;
public $height;
public function __construct($width, $height)
{
$this->width = $width;
$this->height = $height;
}
public function area()
{
return $this->width * $this->height;
}
}
class Circle implements ShapeInterface
{
protected $radius;
public function __construct($radius)
{
$this->radius = $radius;
}
public function area()
{
return $this->radius ** 2 * pi();
}
}
class AreaCalculator
{
public function calculate($shapes)
{
foreach ($shapes as $shape) {
$areas[] = $shape->area();
}
return array_sum($areas);
}
}
I to tyle w temacie OCP
Piękno interfejsów i polimorfizmu . Cudowności z których powinniśmy korzystać zawsze tam gdzie tylko możemy - prawie zawsze.
Na pewno zawsze powinniśmy dostosowywać nasze klasy do reguły OCP!
Dziękuję za lekturę i zapraszam do komentowania i innych moich artykułów .
Życzę ci dobrego dnia, Bywaj!