Zasady programowania
Zasady programowania to zbiór, który się w wielu miejscach wzajemnie wyklucza. Piszę to, abyś się do nich nie zniechęcił. Bo można by przyjąć założenie, że w związku z tym jest zły. I będzie to prawda! Ale jednocześnie fałsz. Ot, taka logika rozmyta, trochę prawdy, trochę fałszu. Jak żyć? Tak, aby było najefektywniej. Aby było prosto i żeby działało. Ale – to też ważne – aby, na ile możesz to przewidzieć, nie powodowało problemów w przyszłości. Tyle, tylko tyle, aż tyle. A teraz przejdźmy do rzeczy!
DRY
Znaczenie słowa Dry w języku angielskim jest dosyć jasne, coś wysuszonego, suchego, albo wytrawnego. W pewien sposób można to przełożyć, ale byłoby to nieco naciągane. DRY to skrótowiec, oznaczający Don’t Repeat Yourself, czyli „Nie powtarzaj się„. Jest to reguła dosyć jasna, jednakże jej przestrzeganie nie zawsze jest proste. Może prowadzić do tworzenia albo jakiś monstrualnych konstrukcji albo zbytniego, niepotrzebnego rozdrobnienia. Zachowaj się z głową, zastanów się, co w danym momencie będzie efektywniejsze – powtórzenie się, czy małe zmiany w kodzie? To nie dogmaty, to nie przykazania – rób z głową. Ale się nie powtarzaj. Ok? Nie powtarzaj się. 😉
KISS
To wie każdy, kto w przedszkolu przeżył swoją pierwszą miłość. A może i nie, bo to również skrótowiec. Ma kilka rozwinięć, niektóre lepsze, niektóre gorsze. Keep It Simple, Stupid. Niech to będzie proste, głupku. Może nie jest to najlżejsze tłumaczenie, ale jak widzę o trzymaniu porządku przez głuptaska, to nie wytrzymuję. Wiem, nie upraszczam. Wyjaśnienia Wikipedii też sprawy nie upraszczają. Ogólnie chodzi o to, aby nie komplikować sobie życia i aby na pierwszy rzut oka wszystko było jasne. Ponoć wywodzi się to od konstruktora samolotów, ma być prosto, aby mechanik mógł to łatwo naprawić. Dobra reguła, na pewno będziemy się jej przyglądać. A może nawet zastosujemy. Czy jest wystarczająco prosto?
SOLID
To największy zbiór zasad, najtrudniejszy do przekazania oschłym, teoretycznym językiem a najłatwiej przekazywać SOLID w praktyce. I będziemy to robić, choć zaczniemy od czystej, brzydkiej teorii.
S – single responsibility principle
Zasada mówiąca, że nigdy nie powinno być więcej niż jednego powodu do modyfikacji klasy. Jaśniej – klasa powinna zajmować się robieniem jednej rzeczy. Jeżeli zmieniasz dwie rzeczy w projekcie i okazuje się, że modyfikujesz jedną klasę – to nie jest dobry znak.
O – open/closed principle
Zasada programowania mówiąca, że elementy systemu takie, jak klasy, moduły, funkcje, metody i im podobne, powinny być otwarte na rozszerzenie, ale zamknięte na modyfikacje. Co to znaczy w praktyce? To, że można zmienić zachowanie takiego elementu, ale bez zmiany jego kodu. Parametryzacja. Tutaj można wdepnąć w pułapkę, trzeba pamiętać o KISS.
L – Liskov substitution principle
Zasada podstawienia Liskov. Barbary Liskov. Chodzi o to, że funkcje używające wskaźników lub referencji do klas bazowych, muszą być w stanie używać również obiektów klas dziedziczących po klasach bazowych, bez dokładnej znajomości tych obiektów. Na polski? Jeżeli funkcja przyjmuje za parametr klasę ClassA, może na niej operować, to powinna umieć operować na klasie ClassB (jeżeli jest to potomek ClassA) bez próby rozpoznania, czy to klasa A, czy B. Więc uważajmy, po kim dziedziczymy!
I – interface segregation principle
Zasada mówiąca że wiele dedykowanych interfejsów jest lepsze niż jeden ogólny. Jest to podobne do pierwszej zasady. Pojedynczy interfejs winien reprezentować jedną logiczną czynność. Bez tworzenia kobył z których i tak nikt nie skorzysta a jak już kiedyś skorzysta – to pewnie z czegoś potomnego, co akurat nie będzie zaimplementowane, bo nikomu się nie chciało.
D – dependency inversion principle
To teraz najdłuższe zdanie teorii, zasada mówiąca że wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych – zależności między nimi powinny wynikać z abstrakcji. Ta-dam. Na szczęście nie jest to takie skomplikowane, na jakie wygląda. Chodzi o to, aby nie definiować zależności (parametrów) na podstawie klas, ale abstrakcji, które są przez klasy obsługiwane. Uzależniamy funkcję od abstrakcji, pozwalając dowolnej klasie tę abstrakcję wypełnić, pozwala to na o wiele łatwiejszą implementację klas i znacznie zwiększa przenośność kodu.