Z czasem mogłem zrozumieć dwie części SOLID - „S” i „O”.
„O” - nauczyłem się otwartej zasady zamkniętej za pomocą wzoru dziedziczenia i strategii.
„S” - nauczyłem się zasady pojedynczej odpowiedzialności podczas uczenia się ORM (logika trwałości jest odbierana obiektom domeny).
W podobny sposób, jakie są najlepsze regiony / zadania do nauki innych części SOLID („L”, „I” i „D”)?
Bibliografia
Odpowiedzi:
Byłem w twoich butach kilka miesięcy temu, aż znalazłem bardzo pomocny artykuł.
Każda zasada jest ładnie wyjaśniona rzeczywistymi sytuacjami, z którymi każdy programista może się spotkać w swoich projektach. Skracam się tutaj i wskazuję na odniesienie - SOLID Software Development, krok po kroku .
Jak wskazano w komentarzach, istnieje jeszcze jedna bardzo dobra lektura pdf - SOLID Software Development firmy Pablo .
Ponadto istnieje kilka dobrych książek, które bardziej szczegółowo opisują zasady SOLID - Dobra książka o rozwoju oprogramowania SOLID .
Edytuj i komentuj krótkie podsumowanie każdej zasady:
„S” - zasada pojedynczej odpowiedzialności wynika z potrzeb firmy, aby pozwolić na zmiany. „Pojedynczy powód do zmiany” pomaga zrozumieć, które logicznie odrębne koncepcje należy zgrupować, biorąc pod uwagę koncepcję biznesową i kontekst, a nie samą koncepcję techniczną.
In another words
, dowiedziałem się, że każda klasa powinna ponosić jedną odpowiedzialność. Obowiązkiem jest po prostu wykonanie przydzielonego zadania„O” - nauczyłem się otwartej zasady zamkniętej i zacząłem „preferować kompozycję nad dziedziczeniem” i jako takie, preferując klasy, które nie mają metod wirtualnych i są prawdopodobnie zapieczętowane, ale ich rozszerzenie wymaga abstrakcji.
„L” - nauczyłem się zasady podstawiania Liskowa za pomocą wzorca repozytorium do zarządzania dostępem do danych.
Ponieważ w komentarzach wspomniano o przydatnym zasobie z CodePlex, w przykładach podano odniesienie do SOLID
źródło
(I) nterface Segregacja i (D) Odwrócenie zależności można nauczyć się poprzez testowanie jednostkowe i kpiny. Jeśli klasy tworzą własne zależności, nie można tworzyć dobrych testów jednostkowych. Jeśli zależą od zbyt szerokiego interfejsu (lub w ogóle nie ma interfejsu), nie jest bardzo oczywiste, co należy kpić, aby wykonać testy jednostkowe.
źródło
Zasada podstawienia Liskowa zasadniczo nie pozwala na nadużywanie dziedziczenia implementacji: nigdy nie należy używać dziedziczenia tylko do ponownego użycia kodu (jest na to skład)! Stosując się do LSP, możesz być całkiem pewien, że faktycznie istnieje „relacja” między twoją nadklasą a twoją podklasą.
Mówi się, że podklasy muszą implementować wszystkie metody podklasy w podobny sposób, jak implementacja metod w podklasie. Nigdy nie należy zastępować metody z implementacją NOP ani zwracać wartości null, gdy nadtyp generuje wyjątek; zgodnie z warunkami Projektu według umowy, podczas nadpisywania metody należy przestrzegać umowy metody z nadklasy. Sposobem obrony przed złamaniem tej zasady jest nigdy nie zastępowanie zaimplementowanej metody; zamiast tego wyodrębnij interfejs i zaimplementuj ten interfejs w obu klasach.
Zasada segregacji interfejsu, zasada pojedynczej odpowiedzialności i zasada wysokiego współdziałania z GRASP są w jakiś sposób powiązane; odnoszą się one do faktu, że jednostka powinna być odpowiedzialna za tylko jedną rzecz, tak aby istniał tylko jeden powód zmiany, aby zmiana była dokonywana bardzo łatwo.
W rzeczywistości mówi, że jeśli klasa implementuje interfejs, musi zaimplementować i zastosować wszystkie metody interfejsu. Jeśli istnieją metody, które nie są potrzebne w tej konkretnej klasie, interfejs nie jest dobry i musi zostać podzielony na dwa interfejsy, który ma tylko metody wymagane przez klasę oryginalną. Można to rozpatrywać z POV, który odnosi się do poprzedniej zasady, ponieważ nie pozwala na tworzenie dużych interfejsów, aby ich implementacja mogła złamać LSP.
Odwrócenie zależności można zobaczyć we wzorcu fabrycznym; tutaj zarówno komponent wysokiego poziomu (klient), jak i komponent niskiego poziomu (indywidualna instancja do utworzenia) zależą od abstrakcji(Interfejs). Sposób zastosowania go w architekturze warstwowej: nie należy definiować interfejsu do warstwy w zaimplementowanej warstwie, ale w wywoływanym module. Na przykład interfejs API do warstwy źródła danych nie powinien być zapisywany w warstwie źródła danych, ale w warstwie logicznej dla biznesu, gdzie należy ją wywołać. W ten sposób warstwa źródła danych dziedziczy / zależy od zachowania zdefiniowanego w logice biznesowej (a więc inwersji), a nie odwrotnie (jak w normalny sposób). Zapewnia to elastyczność w projektowaniu, umożliwiając logice biznesowej pracę bez zmiany kodu, z innym całkowicie innym źródłem danych.
źródło