Jestem studentem, który niedawno dołączył do firmy programistycznej jako stażysta. Na uniwersytecie jeden z moich profesorów mówił, że musimy dążyć do osiągnięcia „niskiego sprzężenia i wysokiej spójności”.
Rozumiem znaczenie niskiego sprzężenia. Oznacza to zachowanie kodu oddzielnych komponentów osobno, aby zmiana w jednym miejscu nie złamała kodu w innym.
Ale co oznacza wysoka spójność. Jeśli oznacza to integrację różnych elementów tego samego elementu ze sobą, nie rozumiem, w jaki sposób staje się to korzystne.
Co oznacza wysoka spójność? Czy można wyjaśnić przykład, aby zrozumieć jego zalety?
Odpowiedzi:
Jednym ze sposobów spojrzenia na spójność w kategoriach OO jest to, czy metody w klasie używają któregokolwiek z prywatnych atrybutów. Korzystając z takich wskaźników, jak LCOM4 (brak spójnych metod), jak zauważył gnat w tej odpowiedzi tutaj , możesz zidentyfikować klasy, które można by refaktoryzować. Powodem, dla którego chcesz zmienić metody lub klasy, aby były bardziej spójne, jest to, że upraszcza to projektowanie kodu innym użytkownikom . Zaufaj mi; większość specjalistów technologicznych i programistów zajmujących się konserwacją pokocha Cię, gdy naprawisz te problemy.
Możesz użyć narzędzi w procesie kompilacji, takich jak Sonar, aby zidentyfikować niską spójność w bazie kodu. Istnieje kilka bardzo częstych przypadków, które mogę wymyślić, gdzie metody mają niską „spójność” :
Przypadek 1: Metoda w ogóle nie jest powiązana z klasą
Rozważ następujący przykład:
Jednej z metod
Discharge()
brakuje spójności, ponieważ nie dotyka ona żadnego z prywatnych członków klasy. W tym przypadku istnieje tylko jeden prywatny użytkownik:_foodValue
. Jeśli nie ma to nic wspólnego z wewnętrznymi elementami klasy, to czy naprawdę tam jest? Metodę można przenieść do innej klasy, którą można nazwać npFoodDischarger
.Robiąc to w JavaScript, ponieważ funkcje są obiektami najwyższej klasy, zrzut może być funkcją bezpłatną:
Przypadek 2: Klasa użyteczności
Jest to w rzeczywistości częsty przypadek, który niszczy spójność. Wszyscy uwielbiają klasy użytkowe, ale zwykle wskazują one na wady projektowe i przez większość czasu baza kodu jest trudniejsza do utrzymania (ze względu na wysoką zależność związaną z klasami użyteczności). Rozważ następujące klasy:
Tutaj widzimy, że klasa narzędziowa musi mieć dostęp do właściwości w klasie
Food
. Metody w klasie użyteczności nie mają w tym przypadku żadnej spójności, ponieważ do wykonania swojej pracy potrzebne są zasoby zewnętrzne. Czy w takim przypadku nie byłoby lepiej mieć metody w klasie, w której pracują same (podobnie jak w pierwszym przypadku)?Przypadek 2b: Ukryte obiekty w klasach użytkowych
Istnieje inny przypadek klas narzędzi, w których znajdują się niezrealizowane obiekty domeny. Pierwszą reakcją szarpiącego kolana, jaką programista ma podczas programowania manipulacji łańcuchem, jest napisanie dla niego klasy użyteczności. Podobnie jak tutaj, który potwierdza kilka typowych reprezentacji ciągów:
To, czego większość nie zdaje sobie sprawy, to to, że kod pocztowy, numer telefonu lub jakakolwiek inna reprezentacja ciągu może być samym obiektem:
Pojęcie, że nie powinieneś „bezpośrednio obsługiwać ciągów” jest szczegółowo opisane w tym blogu przez @codemonkeyism , ale jest ściśle związane ze spójnością, ponieważ sposób, w jaki programiści używają ciągów, umieszczając logikę w klasach narzędzi.
źródło
Wysoka spójność oznacza trzymanie razem podobnych i powiązanych rzeczy, łączenie lub łączenie części, które mają wspólną treść, funkcjonalność, przyczynę lub cel . Innymi słowy, niska spójność może na przykład oznaczać encję funkcji / klasy / kodu, która służy wielu celom, a nie „ do rzeczy ”. Jednym z pomysłów jest zrobienie jednej rzeczy i zrobienie tego dobrze . Inne mogą obejmować oczywisty fakt, że w wielu miejscach nie powielasz podobnej funkcjonalności. Poprawia to także lokalizację bazy kodu, pewne rzeczy znajdują się w określonym miejscu (plik, klasa, zestaw funkcji, ...), a nie są rozproszone.
Jako przykład rozważ klasę, która służy dwóm lub trzem celom: Ładuje / przechowuje zasoby (na przykład plik), a następnie analizuje i wyświetla zawartość. Taka klasa ma niską spójność, ponieważ zarządza co najmniej dwoma oddzielnymi zadaniami, które w ogóle nie są powiązane (we / wy pliku, analiza i wyświetlanie). Projekt o wysokiej spójności mógłby wykorzystywać odrębne klasy do ładowania i przechowywania zasobu, analizowania go, a następnie wyświetlania.
Z drugiej strony, niskie sprzężenie ma na celu zachowanie oddzielnych elementów - tak, aby oddziaływały ze sobą jak najmniej, co następnie zmniejsza złożoność i upraszcza projekt.
źródło
Oznacza to, że części danego obiektu są ściśle związane z funkcją obiektu. Oznacza to, że w obiekcie jest bardzo mało odpadów lub nie ma ich wcale pod względem funkcji lub odpowiedzialności. To z kolei może lepiej zrozumieć, do czego dany obiekt ma być używany.
źródło