Nie ma na to jednoznacznej odpowiedzi. Chociaż pytanie jest wąskie, wyjaśnienia nie są.
Dla mnie jest to coś takiego jak Razam Razor, jeśli chcesz. To ideał, w którym próbuję zmierzyć mój obecny kod. Trudno to wyrazić prostymi i prostymi słowami. Inną metaforą byłby »jeden temat«, który jest tak abstrakcyjny, tzn. Trudny do zrozumienia, jak »jedna odpowiedzialność«. Trzecim opisem byłoby „zajmowanie się jednym poziomem abstrakcji”.
Co to znaczy praktycznie?
Ostatnio używam stylu kodowania, który składa się głównie z dwóch faz:
Fazę I najlepiej opisać jako twórczy chaos. W tej fazie piszę kod, gdy myśli płyną - tj. Surowy i brzydki.
Faza II jest całkowitym przeciwieństwem. To jest jak sprzątanie po huraganie. To wymaga najwięcej pracy i dyscypliny. A potem patrzę na kod z perspektywy projektanta.
Obecnie pracuję głównie w Pythonie, co pozwala mi później myśleć o obiektach i klasach. Pierwsza faza I - piszę tylko funkcje i rozkładam je prawie losowo w różnych modułach. W fazie II , kiedy już wszystko zaczęło działać, przyjrzałem się bliżej modułowi, który dotyczy danej części rozwiązania. A gdy przeglądam moduły, pojawiają się dla mnie tematy . Niektóre funkcje są powiązane tematycznie. To są dobrzy kandydaci na zajęcia . A po tym, jak zamieniłem funkcje w klasy - co jest prawie gotowe z wcięciem i dodaniem self
do listy parametrów w pythonie;) - używam SRP
jak Razor Razor do rozszyfrowania funkcjonalności innych modułów i klas.
Obecnym przykładem może być pisanie niewielkiej funkcjonalności eksportu innego dnia.
Potrzebny był plik CSV , Excel i połączone arkusze Excela w zipie.
Zwykła funkcjonalność została wykonana w trzech widokach (= funkcje). Każda funkcja wykorzystywała wspólną metodę określania filtrów i drugą metodę odzyskiwania danych. Następnie w każdej funkcji miało miejsce przygotowanie eksportu i zostało dostarczone jako odpowiedź z serwera.
Wymieszano zbyt wiele poziomów abstrakcji:
I) obsługa przychodzących / wychodzących wniosków / odpowiedzi
II) określanie filtrów
III) odzyskiwanie danych
IV) transformacja danych
Łatwym krokiem było użycie jednej abstrakcji ( exporter
) do zajęcia się warstwami II-IV w pierwszym kroku.
Pozostał tylko temat dotyczący zapytań / odpowiedzi . Na tym samym poziomie abstrakcji jest wydobywanie parametrów żądania, co jest w porządku. Miałem więc za ten pogląd jedną „odpowiedzialność”.
Po drugie, musiałem rozbić eksportera, który, jak widzieliśmy, składał się z co najmniej trzech innych warstw abstrakcji.
Określanie kryteriów filtrowania i faktyczne wycofywanie jest prawie na tym samym poziomie abstrakcji (filtry są potrzebne, aby uzyskać odpowiedni podzbiór danych). Poziomy te zostały umieszczone w czymś w rodzaju warstwy dostępu do danych .
W następnym kroku podzieliłem rzeczywiste mechanizmy eksportu: tam, gdzie potrzebne było zapisywanie do pliku tymczasowego, podzieliłem to na dwie „obowiązki”: jedną do faktycznego zapisu danych na dysk i drugą część, która dotyczyła faktycznego formatu.
Wraz z tworzeniem się klas i modułów stało się jasne, co było gdzie. I zawsze ukryte pytanie, czy klasa robi za dużo .
Jak określasz obowiązki każdej klasy i jak określasz odpowiedzialność w kontekście SRP?
Trudno podać przepis do naśladowania. Oczywiście mógłbym powtórzyć tajemniczą »jeden poziom abstrakcji« - zasadę, jeśli to pomoże.
Przeważnie dla mnie jest to rodzaj „artystycznej intuicji”, która prowadzi do obecnego projektu; Modeluję kod tak, jak artysta może rzeźbić glinę lub malować.
Wyobraź sobie mnie jako kodującego Boba Rossa ;)