Jestem studentem, który niedawno dołączył jako stażysta do firmy programistycznej. Na uniwersytecie jeden z moich profesorów mawiał, że musimy dążyć do osiągnięcia „niskiego sprzężenia i wysokiej spójności”.

Rozumiem znaczenie niskiego sprzężenia. Oznacza to oddzielne przechowywanie kodu oddzielnych komponentów, tak aby zmiana w jednym miejscu nie zepsuła kodu w innym.

Ale co to znaczy wysoka spójność. Jeśli oznacza to dobre zintegrowanie różnych części tego samego komponentu ze sobą, nie rozumiem, jak to jest korzystne.

Co to znaczy wysoka spójność? Czy można wyjaśnić przykład, aby zrozumieć jego zalety?

Komentarze

  • możliwy duplikat Czy istnieją Wskaźniki spójności i łączenia?
  • Czy artykuł na Wikipedii nie zawiera wystarczającej odpowiedzi na Twoje pytanie? en.wikipedia.org/wiki/Cohesion_(computer_science)
  • Jest dobry artykuł na ten temat pod adresem: msdn.microsoft.com/en-us/magazine/cc947917.aspx
  • @EoinCarroll: Niestety, aktualny artykuł na Wikipedii nie daje żadnego dobrego konkretne przykłady , z którymi mogą pracować nowi programiści. Teoria jest dobra i wszystko, ale nie ' tak naprawdę nie trzymasz się, dopóki ' nie popełnisz błędów związanych z niską spójnością. Wysoka spójność jest jednym z tych tematów, które zajęły mi kilka lat programowania, aby w pełni zrozumieć, dlaczego jest to ważne i jak to osiągnąć.
  • Tak naprawdę nigdy nie rozumiałem spójności, dopóki nie przeczytałem Czysty kod. Ty też powinieneś.

Odpowiedź

Jednym ze sposobów spojrzenia na spójność w kategoriach OO jest to, że metody w klasa używa dowolnego z atrybutów prywatnych. Korzystając z metryk, takich jak LCOM4 (brak spójnych metod), na co zwraca uwagę gnat w tej odpowiedzi tutaj , możesz zidentyfikować klasy, które można refaktoryzować. Powodem, dla którego chcesz, aby metody lub klasy były bardziej spójne, jest to, że ułatwia innym korzystanie z kodu . Zaufaj mi; większość techników i programistów konserwacyjnych będzie Cię zachwycać, gdy rozwiążesz te problemy.

Możesz użyć narzędzi w procesie kompilacji, takich jak Sonar , zidentyfikować niską spójność w bazie kodu. Jest kilka bardzo typowych przypadków, które przychodzą mi do głowy, gdy metody mają niską „spójność” :

Przypadek 1: Metoda w ogóle nie jest powiązana z klasą

Rozważmy następujący przykład:

 public class Food { private int _foodValue = 10; public void Eat() { _foodValue -= 1; } public void Replenish() { _foodValue += 1; } public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Jedna z metod , Discharge(), brakuje spójności, ponieważ nie dotyka żadnego z prywatnych członków klasy. W tym przypadku jest tylko jeden członek prywatny: _foodValue. Jeśli nie robi nic z elementami wewnętrznymi klasy, to czy naprawdę tam należy? Metoda może zostać przeniesiona do innej klasy, której można by nazwać np. FoodDischarger.

 // Non-cohesive function extracted to another class, which can // be potentially reused in other contexts public FoodDischarger { public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

W tobie „robisz to w Javascript, ponieważ funkcje są obiektami pierwszej klasy, może być funkcją bezpłatną:

 function Food() { this._foodValue = 10; } Food.prototype.eat = function() { this._foodValue -= 1; }; Food.prototype.replenish = function() { this._foodValue += 1; }; // This Food.prototype.discharge = function() { console.log("Nnngghhh!"); }; // can easily be refactored to: var discharge = function() { console.log("Nnngghhh!"); }; // making it easily reusable without creating a class  

Przypadek 2: Klasa użyteczności

To jest właściwie powszechny przypadek, który łamie spójność. Każdy kocha klasy użyteczności, ale zwykle wskazują one na wady projektowe i przez większość czasu utrudniają utrzymanie bazy kodu (z powodu dużej zależności związanej z klasami użytkowymi). Rozważ następujące klasy:

 public class Food { public int FoodValue { get; set; } } public static class FoodHelper { public static void EatFood(Food food) { food.FoodValue -= 1; } public static void ReplenishFood(Food food) { food.FoodValue += 1; } }  

Tutaj widzimy, że klasa narzędziowa wymaga dostęp do właściwości w klasie Food. Metody w klasie użytkowej nie mają w tym przypadku żadnej spójności, ponieważ do wykonania swojej pracy wymagają zewnętrznych zasobów. W tym przypadku nie byłoby lepiej mieć metody w klasie, z którą „pracują” ( podobnie jak w pierwszym przypadku)?

Przypadek 2b: Ukryte obiekty w klasach użytkowych

Jest jeszcze jeden przypadek klas narzędziowych, w których istnieją niezrealizowane obiekty domeny. Pierwsza reakcja odruchowa programista podczas programowania manipulacji na łańcuchach ma napisać dla niego klasę narzędziową.Tak jak tutaj, która weryfikuje kilka typowych reprezentacji ciągów:

 public static class StringUtils { public static bool ValidateZipCode(string zipcode) { // validation logic } public static bool ValidatePhoneNumber(string phoneNumber) { // validation logic } }  

Co większość nie zdaje sobie sprawy z tego, że kod pocztowy, numer telefonu lub jakakolwiek inna reprezentacja ciągu może być samym obiektem:

 public class ZipCode { private string _zipCode; public bool Validates() { // validation logic for _zipCode } } public class PhoneNumber { private string _phoneNumber; public bool Validates() { // validation logic for _phoneNumber } }  

Pogląd, że nie należy bezpośrednio obsługiwać łańcuchów znaków, jest szczegółowo opisany w tym poście na blogu @codemonkeyism , ale jest ściśle związany ze spójnością, ponieważ sposób, w jaki programiści używają łańcuchów, umieszczając logikę w klasach narzędzi.

Komentarze

Odpowiedź

Wysoka spójność oznacza trzymanie razem podobnych i powiązanych rzeczy, łączenie lub łączenie części, które dzielą zawartość, funkcjonalność, powód lub cel . Innymi słowy, niska spójność może na przykład oznaczać jednostkę funkcji / klasy / kodu, która służy wielu celom, a nie jest „ na temat ”. Jednym z pomysłów na prowadzenie jest zrobienie jednej rzeczy i zrobienie tego dobrze . Inne mogą obejmować oczywisty fakt, że nie powielasz podobnej funkcjonalności w wielu miejscach. Poprawia to również lokalizację bazy kodu, pewne rodzaje rzeczy znajdują się w określonym miejscu (plik, klasa, zestaw funkcji, …) zamiast być rozproszonym.

Jako przykład rozważmy 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 Taka klasa ma niską spójność, ponieważ zarządza co najmniej dwoma oddzielnymi zadaniami, które nie są w ogóle 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 oddzielenie różnych rzeczy – tak, aby współdziałały ze sobą tak mało, jak to możliwe, co zmniejsza złożoność i upraszcza projekt.

Odpowiedź

Oznacza to, że części obiektu są ściśle związane z funkcją obiektu. Oznacza to, że w obiekcie jest bardzo mało lub nie ma żadnych odpadów pod względem funkcji lub odpowiedzialności. To z kolei może poprawić zrozumienie, do czego dany obiekt ma służyć.

Komentarze

  • nie ' czy dotyczy to również wyższego poziomu niż tylko obiekty? np. grupowanie obiektów / funkcji związanych z zadaniem w przestrzeniach nazw?

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *