2. Always code as if the guy who ends up
maintaining your code will be a
violent psychopath
who knows where you live.
3.
4. Problems
• Does our code solves challenges and
business problems that it should
• Is our code human readable
• Is our code maintainable
• Is our code extensible, scalable
• Is our code granular and reusable
7. Open-close principle
System elements should be open for extension but closed
for modification
Lights can be dismantled without taking out an engine
8. Liskov substitution principle
Object of a derived class should be able to replace an object of the base class without
bringing any errors in the system or modifying the behavior of the base class
If it looks like a duck, and quack like a duck, but it needs batteries,
You probably have wrong level of abstraction
9. Interface segregation principle
Many specialized interfaces are better than one almighty.
A client should never be forced to implement an interface that it
doesn’t need or clients shouldn’t be forced to depend on methods
It’s not a good idea to mix electricity and water in one place
10. Dependency inversion principle
The high level module must not depend on the low level module.
Both modules should depend on abstractions.
Abstractions should not depend on details. Details should depend on
abstractions.
You don’t need to know how the engine is build to start it
12. KISS DRY YAGNI
YAGNI DRY
Don’t Repeat
Yourself
WET
We Enjoy Typing
Write Everything Twice
13. KISS DRY YAGNI
YAGNI DRY KISS
Keep It Simple Stupid
Keep It Simple, Stupid
Keep it Simple Silly
Keep It Short & Simple
Keep It Small & Simple
Keep It Simple
&Straightforward
Dlaczego rozmawiamy o solidzie?
Teoretyczne podstawy jezyka
paradygmaty języka i podstawy wzorcow projektowych
MSDN przyklady tak mowia.
Brak duzych przykladow – duzych systemow.
Architektura I utrzymanie system przez lata
Łatwo jest użyć wzorców do małych programów typu uniwersyteckiego, natomiast nie jest już tak prostą sprawą użycie ich w istniejących często bardzo dużych systemach, dodatkowo istniejące systemy zazwyczaj są pisane od wielu lat i nie zawsze są dobrze dostosowane do stosowania wzorców.
Problemy przed nami programistami I przed samym systemem.
Każdy kod który” został napisany jest już Legacy Code (nawet napisałam go ja 15 minut temu).
Czy nasz program rozwiązuje problem
Czy nasz kod jest czytelny dla człowieka
Czy nasz kod jest łatwo utrzymywalny
Czy nasz kod jest łatwo rozszerzalny w razie potrzeby
Czym granularność naszego kodu jest wystarczająca czy też może powinien być rozbity na mniejsze fragmenty i robić mniej rzeczy na raz.
Aby dobrze posługiwać się wzorcami trzeba je dobrze poznać.
SOLID stara sie odpowiedziec na te pytania, dac nam narzedzia do budowania lepszego oprogramowania.
SOLID to zasady zebrane i spisane, choć nie stworzone przez Roberta Martina zwanego wujkiem Bobem.
Gang czworga. Design patgerns 1994 wspierani
Przez booth’a tworce umla 1996
Wujek Bob jest bardzo charyzmatyczną i marketingową postacią przedstawiającą dobre praktyki programowania. Wart jest śledzenia. Jednak warto też nałożyć filtr ponieważ nie wszystko jest możliwe do zaimplementowania. A moim zdaniem najlepiej zastosować zasadę złotego środka czysty kod jest dobry jeśli nie przesadzimy z jego puryzmem.
S - Single responsibility principle
Zasada pojedynczej odpowiedzialności. Kasa nie powinna mieć więcej niż jeden powód do modyfikacji.
Kod powinien robić jedną rzecz, tylko jedną rzecz i robicie ją dobrze.
Jedna rzecz
= jest łatwiej zrozumiały,
= mniejsze prawdopodobienstwo koniecznosci modyfikacji
= mniej dotkliwe skutki uboczne modyfikacji
Nie zawsze jest wiadome i jasne czym jest "jedna rzecz"
(mówimy zarówno o poziomie projektu, modułu, klasy jak i metody).
Przykład - użytkownik
- "Wylicz podwyżkę"
- "Zmień dane osobowe"
Tutaj oczywiście mamy dwie różne odpowiedzialności, które potrafiliśmy łatwo zidentyfikować i nazwać.
Na bazie jednych pomysłów rodzą się kolejne.
Patrząc na zapis do bazy:
-aktualizacja danych, dodanie nowych danych i usuwanie danych
-odczyt danych z bazy danych . wiele wariantów sortowaniem wyszukiwanie, zawezanie zakresu
Tutaj ta teoretycznie jedna odpowiedzialności jaką jest operowanie danymi przechowywanymi podzielona jest na dwie niezależne od siebie części czyli dostęp typu odczyt oraz dostęp typu zmiana. Cała ta idea leży u podstaw CQRS.
Elementy systemu powinny być otwarte na rozszerzanie ale zamknięte na modyfikację.
jak to powinniśmy napisać kod raz i już nigdy do niego nie wrócić?
Nie powinniśmy go modyfikować za to możemy go rozszerzać?
Kazda modyfikacja moze wprowadzic bledy. W danej metodzie I zaleznosciach
Przyklad wysokiego poziomu
WordPress.
Wtyczki
Sredni poziom
Feacher toggling/ feacher switching
Niski poziom
String
Extension method
Wyjątki
1 Jeśli kod zawiera błędy to powinniśmy te błędy rozwiązać
2 Jeśli chcemy zrefaktoryzowac kod to możemy, o ile nie przedstawimy w ten sposób nowych błędów. Oczywiście refaktoryzację przedstawiamy tylko dlatego że nasz kod zaczyna łamać zasady SOLID.
3 Trochę kontrowersyjna zasada, ale możemy zmieniać kod jeśli nie przedstawimy w ten sposób nowych błędów a klienci naszego kodu nie odczują zmiany czyli że nie będą musieli dostosowywać się do zmian.
Single Responsibility I Open Close = podzial kodu, trochę burdel.
Zacznijmy sprzatac
Liskov substitution principle.
Zasada mówi że powinniśmy być w stanie zastąpić klasa dowolną subklasa tej klasy bez potrzeby dodatkowej modyfikacji kodu.
rozszerzenie i obostrzenie zasad dziedziczenia,
ponieważ wszędzie tam gdzie możemy użyć klasy bazowej możemy użyć też klasy dziedziczącej. Jezyk nie pozwoli nam inaczej (np na odwrot). Wiekszosc zasady Liskov daje nam jezyk out of the box. Jedyne co to exception…
Wymienne korzystanie z subklas.
Liskov dodatkowe zasady
1 Warunki wstępne nie mogą zostać wzmocnione przez podklasa
2 Warunki oczekiwane (wyjściowe) nie mogą zostać osłabione przez podklasa
3 zmienne które nie są zmieniane przez metodę w klasie bazowej nie mogą być również zmieniane przez metodę klasy dziedziczącej.
Klasa dziedzicząca nie może wprowadzać nowych typów: przykład exceptiony (nie może go zawęzić/wyspecjalizować. )
Wszystko to robimy ze względu na klientów naszego kodu, aby nie musieli oni modyfikować obsługi kontraktów na które się zobowiązaliśmy.
Pułapka źle wybranej abstrakcji.
Przykład kaczki
Latanie , karminie (exception w rubber duck)
Zly poziom abstrakcji
Ze zle wybranej abstrakcji latwiej jest wyjsc interfejsami – wystarczy pamietac o nie wyrzucaniu exceptionow.
Liskov jest praktycznie niepokazywalny – mozna pokazac tylko zlamanie tej zasady.
I - Interface segregation principle
Zasada segregacji interfejsów mówi że wiele specyficznych interfejsów jest lepsze niż jeden interfejs "robiący wszystko". Klienci nie powinni być zmuszani to implementacji metod których nie potrzebują.
Ratujemy kaczke interfejsami
Dzielimy interfejsy.
Latanie
Karmienie
Material…
Wybrnelismy ze zlej abstrakcji
Best – dobra abstrakcja i male interfejsy.
Mamy:
Male wyspecjalizowane klasy z interfejsami przygotowane na niemodyfikowanie tylko rozszerzanie. Dobra abstrakcja, wszystko gra.
DI żeby polaczy
W tym momencie mamy już bardzo małe wyspecjalizowane klasy które posiadają swoje jeszcze mniejsze wyspecjalizowane interfejsy wszystko to może być w wielu wersjach które możemy dowolnie wymieniać.
Aby wszystko teraz połączyć i nie zepsuć powinniśmy zastosować zasadę odwracania zależności.
D - Dependency inversion principle
Zasada odwróconej zależności mówi że moduły wysokiego poziomu nie powinny być zależne od modułów niskiego poziomu, oba poziomy modułów powinny być zależne od abstrakcj.
Oraz że abstrakcje nie powinny zależeć od detali to detale powinny być zależne od abstrakcji.
używanie abstrakcji w każdej interakcji pomiędzy modułami, klasami.
Zawsze powinniśmy polegać tylko na abstrakcji nie na konkretnej implementacji.
Przykład - samochód
nie potrzebujemy wiedzieć jak zbudować silnik ani jaki silnik jest w samochodzie, żeby móc go włączyć ponieważ wszystkie samochody maja interfejs stacyjki który zapewnia start silnika.
W praktyce do realizacji tej zasady używamy mechanizmu Dependency Injection oraz kontenerów,
wyręczają w inicjalizacji klas implementujących wymagane interfejsy.
Bardzo trudno jest stworzyć system który będzie spełniał wszystkie zasady SOLID.
Mimo że te dobre praktyki mają pomagać w tworzeniu niezawodnego, łatwo rozszerzalnego, testowalnego oprogramowania prawda jest taka że stosowanie zasad SOLID wymaga dużego nakładu pracy na którego często nie ma dostępnych wystarczających zasobów.
Kilka akronimow:
YAGNI – You Aint Gonna Need It.
Biznesowo i architektonicznie
Nie budowanie funkcjonalności które nie są nam potrzebne teraz.
plany długofalowe, ale nie teraz.
Tendencja programistow – teraz będzie taniej i lepiej.
Wynik:
Niepotrzebny koszt budowy,
Koszt utrzymania,
Kosz testow.
Zmiana wymagan = reimplementacja.
Piszmy więc tylko to czego potrzebujemy/ czego potrzebuje biznes.
Programistyczne.
patrzenie w tył czyli co zrobić z kodem po refaktoringu.
Tendencja programistów - "może się przydać".
W najlepszym wypadku = komentujemy kod.
W najgorszym wypadku = zostawiamy zombi kod który nie jest z niczym powiązany nie jest testowany niby jest martwy ale nadal żyje a w dodatku jest upchnięty w schowku z którego gdy go wypuścimy może nam tylko zjeść mózg.
Najlepiej wyrzucić.
Repozytorium pamięta
DRY
Don't Repeat Yourself.
biznesowo.
Każdy kawałek wiedzy w systemie powinien być reprezentowany/zaimplementowany tylko raz w całym systemie.
W kontekście biznesowym mówimy tylko i wyłącznie o funkcjonalnościach jako całości nie przejmujemy się powtorzeniem kodu. Oczywiście zrealizować pojedyńczą implementację możemy wybierając np. kompozycję ponad dziedziczenie, jednak nadal rozmawiamy o funkcjonalnościach.
Programistycznie
Leniwy programista pisze raz a potem uzywa.
Odwrotnością DRY jest WET które tłumaczy się na We Enjoy Typing albo Write Everything Twice.
Rozmawiamy nie tylko o powtarzającym się kodzie ale również powtarzających się operacjach które mogą być zautomatyzowane (jak DevOps)
KISS
Keep It Simple Stupid
Keep It Simple, Stupid
Keep it Simple Silly
Zmieniając położenie przecinka w podstawowym tłumaczeniu zmieniamy troszkę wydźwięk tego stwierdzenia. Jednak nie obrażając adresata stwierdzenia chcemy aby nasze rozwiązanie było głupio proste, maksymalnie uproszczone i zrozumiałe dla każdego.
tworzyć rozwiązania proste nie łatwe.
(bo nie warto robić rzeczy łatwych, ale dążenie do prostoty jest dążeniem do doskonałości)
Programistycznie
patrząc w przód
i wymyślając wspaniały mechanizm który będzie przygotowany na wszystkie ewentualności nieważne jaka jest podstawowa funkcjonalność.
gotowi na wszystko.
Z najlepszym przypadku jest to "tylko" over-enginering i kod tak piękny że nikt nie potrafi go zrozumieć - ale jest np. jednolinijkowy.
W najgorszym przypadku
Programisci się zapetlaja w DRY I KISS
I tworza frameworki.
Trudne w używaniu zrozumieniu i utrzymaniu.
KISS jest dążeniem do prostoty.
Zawsze pamiętajmy o zdrowym rozsądku i złotym środku