Przy okazji sprzątania biurka ze szpargałów ze studiów, wpadły mi w ręce całkiem zgrabne wykłady na temat projektowania obiektowego (czyli – planowania jak wykonać i zaprogramować projekt, np. za pomocą diagramów UML). Może przyda się – jako szybka powtórka pojęć, które każdy programista „obiektowy” znać powinien.
(Podejście momentami niestety dość suche i akademickie, wpis chciałabym więc sukcesywnie uzupełniać o bardziej „ludzkie” definicje.)
Interfejs – klasa bez atrybutów, nie opisująca implementacji metod, posiadająca wyłącznie usługi i operacje abstrakcyjne.
Abstrakcja – pomijanie nieistotnych szczegółów w celu ukazania tych informacji, które są w danym przypadku istotne. W połączeniu ze skalą (czyli „taką organizacją, aby dowolnie duża wartość była przejrzysta dla obserwatora”) można sobie wyobrazić to jako schemat blokowy (lub UML) – ogólny gdy jest „oddalony”, a w miarę zwiększania skali – bardziej szczegółowy. Zgodnie z zasadą skali, logicznie powiązane klasy powinny znajdywać się w jednym pakiecie.
Hermetyzacja – ukrywanie szczegółów implementacji za interfejsami, aby dana „struktura” (klasa, moduł, pakiet, biblioteka…) zamykała w sobie możliwie jedną funkcjonalność.
Interfejsy powinny ukrywać jak najwięcej szczegółów implementacyjnych (czyli lepiej, aby posiadały jedną metodę typu „rób to”, niż kilka metod, konfiguracji, kilka metod wykonania danej czynności – programista implementujący taki interfejs w swojej klasie poczuje się zdezorientowany).
Dane oraz operujące na nich algorytmy powinno zostać umieszczone w jednym obiekcie.
Wartości atrybutów powinny zostać udostępniane tylko przez usługi (gettery, settery albo bardziej rozbudowane metody), dzięki czemu można go z zewnątrz pobrać, a niekoniecznie można go modyfikować.
Hermetyzacja powoduje duże rozdrobnienie struktury, ponieważ każda klasa zajmuje się jedną rzeczą.
Spójność – miara określająca stopień powiązań między metodami wewnętrznymi klasy/modułu („stopień skupienia zobowiązań”). Klasa niespójna to klasa, która odpowiada za dużo różnych spraw. Takie klasy powinno się rozbijać na mniejsze.
Sprzężenie – miara określająca stopień powiązań między klasami lub modułami.
Przeważnie niska spójność = duże sprzężenie. Powinno dążyć się do wysokiej spójności i małego sprzężenia (dzięki czemu łatwiejsze będzie np. testowanie jednostkowe).
5 zasad SOLID:
- Zasada pojedynczej odpowiedzialności (Single responsibility principle) – jedna klasa powinna odpowiadać za jedno zadanie. Być mała i przejrzysta. Prowadzi to do rozdrobnienia i do tworzenia warstwowej struktury systemu.
- Zasada otwarte-zamknięte (Open/closed principle)
- Zasada podstawienia Liskov (Liskov substitution principle)
- Zasada segregacji interfejsów (Interface segregation principle) – interfejsy powinny zawierać tylko te metody, których używają logicznie połączone z nimi klasy. Interfejsy, które mają dużo różnych, niepowiązanych ze sobą metod, wprowadzają wysokie sprzężenie w projekcie oraz niską spójność klas.
- Zasada odwrócenia zależności (Dependency inversion principle)