Kilka dni temu rozmawiałem z doktorantem ds. Inżynierii oprogramowania, a ona powiedziała mi kiedyś:
Utrzymuj swoje klasy i metody tak małe, jak to możliwe
I zastanawiam się, czy to zawsze dobra praktyka.
Chodzi mi na przykład o to, czy warto mieć klasę z tylko 2 osobami towarzyszącymi? Na przykład w niektórych metodach potrzebuję par liczb całkowitych do pracy. Czy powinienem napisać klasę „PairOfIntgers”?
Czy ten sposób myślenia może „rozbić” kod na zbyt wiele części?
code-quality
coding-style
Florents Tselai
źródło
źródło
"As small as possible, but no smaller."
Odpowiedzi:
W tej radzie jest ziarno prawdy, ale IMHO nie jest zbyt dobrze wyrażone, dlatego łatwo ją źle zrozumieć i / lub doprowadzić do głupiej skrajności. W każdym razie powinna to być zasada praktyczna, a nie twarde prawo. I zawsze powinieneś sugerować w takich regułach klauzulę „w rozsądnych granicach” lub „ale nie zapomnij o zdrowym rozsądku” :-)
Ziarno prawdy polega na tym, że w praktyce klasy i metody zawsze rosną z natury, a nie kurczą się . Naprawiono błąd tutaj, małe rozszerzenie funkcji, obsługujące specjalny przypadek tam ... i voila, twoja niegdyś schludna i mała klasa zaczyna wzdęcia. Z czasem twój kod prawie nieuchronnie staje się potwornym bałaganem spaghetti - chyba że aktywnie zwalczysz tę tendencję poprzez refaktoryzację . Refaktoryzacja prawie zawsze daje wiele mniejszych klas / metod z kilku dużych. Ale oczywiście istnieje rozsądna granica miniaturyzacji. Celem refaktoryzacji nie jest posiadanie mniejszych klas i metod per se, ale uczynienie kodu czystszym, łatwiejszym do zrozumienia i utrzymania. W pewnym momencie zmniejszenie metod / klas zaczyna zmniejszać czytelność, zamiast ją zwiększać. Celuj w to optymalne. Jest to rozmazany i ruchomy obszar docelowy, więc nie musisz go trafiać w miejscu. Po prostu popraw kod nieco, gdy zauważysz jakiś problem .
źródło
Ważniejszą kwestią do podkreślenia tutaj jest tworzenie dobrych abstrakcji . Małe klasy, które są luźno połączone i mają wysoką spójność, są wynikiem dobrych abstrakcji .
Czasami sensowne jest kapsułkowanie dwóch liczb całkowitych w klasie. Zwłaszcza jeśli chcesz mieć metody „dołączone” do tej klasy, aby również opisać, w jaki sposób można manipulować tymi atrybutami i upewnić się, że chronisz je przed innymi częściami programu, które je zmieniają.
Kolejną zaletą stworzenia klasy w tym przypadku jest to, że klasa może ewoluować znacznie lepiej / ładniej niż, powiedzmy, struktura danych niższego poziomu, taka jak mapa lub lista.
Po trzecie, dobra abstrakcja może znacznie poprawić czytelność. Klasy, które stosują się do SRP są zazwyczaj znacznie łatwiejsze do zrozumienia dla człowieka niż klasy, które tego nie robią.
I jako ostatnia uwaga ... bez względu na to, jak dobry jesteś studentem ... aby zrozumieć OOP i dobre abstrakcje, a kiedy z nich korzystać, potrzebujesz doświadczenia. Musisz napisać zły kod i przejść przez ból, aby go utrzymać. Musisz zobaczyć, jak inni piszą dobry kod, aby rozwinąć twoją wiedzę na temat tego, co jest „dobre” i co będzie problemem w dalszej kolejności… Więc nie pobijaj się, jeśli po prostu go nie rozumiesz.
źródło
Anty-wzorzec God Object jest prawdopodobnie tym, do czego prawdopodobnie nawiązała. Mam tendencję do myślenia, że jeśli w opisie klasy mam „i”, powinienem mieć dwie klasy. Jeśli mam więcej niż dziesięć wierszy kodu w metodzie / funkcji, powinienem to rozerwać. Jako kod piracki, są one bardziej wytycznymi niż zasadami.
źródło
W programowaniu obiektowym zasada pojedynczej odpowiedzialności stwierdza, że każdy obiekt powinien mieć jedną odpowiedzialność i że odpowiedzialność powinna być całkowicie zamknięta w klasie. Zwykle robisz więcej niż jedną rzecz, jeśli twoja klasa staje się zbyt duża. W twoim przypadku klasa jest tylko klasą danych, która przechowuje dane, co jest w porządku. Nie powinieneś nazywać klasy PairOfInteger. Co opisują liczby całkowite? W zależności od twojego scenariusza może również wystarczyć krotka (jak w C #). I możesz pomyśleć o rozpórce zamiast o klasie.
Staraj się, aby twoje zajęcia były małe. A metody jeszcze mniejsze. Może 10 linii?!? Obecnie staram się używać projektowania przepływów i komponentów opartych na zdarzeniach, które wydają się pomagać w utrzymaniu małych klas. Najpierw bałem się dostać na wiele zajęć, ale to naprawdę działa !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx
źródło
Spraw, aby rzeczy były tak proste, jak to możliwe, ale nie prostsze. To jest zasada, którą staram się przestrzegać. Czasami sensowne jest, aby klasa robiła to, co ściśle mówiąc, oznacza więcej niż jedną rzecz, jeśli te rzeczy są powiązane na jakiś wspólny temat . Spójrz na .NET; istnieje mnóstwo klas, które implementują dużą liczbę interfejsów, każda z własną listą wymaganych elementów. Metoda może w końcu stać się nieco długa, jeśli wykona coś złożonego z wieloma pośrednimi krokami, z których wszystkie są ze sobą połączone, a zatem nie nadają się zbyt dobrze do dalszego refaktoryzacji. (Refaktoryzacja w celu skrócenia metod powinna ostatecznie dotyczyć czytelności i łatwości konserwacji; jeśli długa metoda jest bardziej czytelna i / lub możliwa do utrzymania niż krótka, wszystko inne równe, wezmę tę długą każdego dnia.)
Moim zdaniem błędne jest jedynie „uczynienie klas i metod jak najmniejszymi”. Prawdziwym wyzwaniem jest, jak wskazuje @c_maker, zapewnienie dobrych abstrakcji. Twój przykład grupowania dwóch liczb razem jest świetny, na przykład, jeśli pracujesz nad implementacją arytmetyki liczb zespolonych lub jeśli w systemie Unix musisz odwoływać się do kontekstu użytkownika / grupy. Nie ma większego sensu, jeśli liczby reprezentują, powiedzmy, identyfikator faktury i identyfikator produktu, które należy dodać do tej faktury.
źródło
To dobra rada, ale trzeba ją wdrożyć nieco inteligentnie. Zdecydowanie nie podążaj za tym na ślepo.
Kiedy patrzę na mój kod, wiem, czy metoda jest zbyt duża. Jeśli robi za dużo i byłby zbyt trudny do odczytania, oznacza to czas refaktoryzacji.
Oto dobry przykład: masz pętlę i może masz 60 linii kodu w tej metodzie. W takim przypadku prawdopodobnie nadszedł czas na refaktoryzację, ponieważ prawdopodobnie robisz za dużo w tej metodzie.
Ale nie jest to trudna i szybka zasada. To tylko coś, czego można się nauczyć, robiąc. Inni programiści, z którymi współpracujesz, nie zawsze się z tym zgadzają i mogą cię wezwać do przeglądu kodu lub cokolwiek innego.
źródło
Wujek Bob mówi, że powinieneś refaktoryzować / podzielić / wyodrębnić swoje metody, dopóki nie będzie możliwe ich zmniejszenie . Zwykle kończy się to kilkoma metodami z 3 lub 4 liniami każda. Kiedy dostajesz zbyt wiele metod, musisz stworzyć więcej klas.
Jeśli spróbujesz stosować się do SRP i jednego poziomu abstrakcji dla każdej metody, zasady te dobrze ci służą. Przynajmniej dobrze mi służą. Celowanie w „tak mały, jak to możliwe” daje mi rozsądne małe metody, ponieważ zwykle nie udaje mi się osiągnąć celu.
I zawsze łatwiej jest zrozumieć mniejsze klasy. Śmiało, przeczytaj „Wyczyść kod”
źródło