Co oznacza „niskie sprzężenie i wysoka spójność”

151

Mam problemy ze zrozumieniem tego stwierdzenia low in coupling and high in cohesion. Przeszukałem go i dużo o tym czytałem, ale nadal trudno mi to zrozumieć.

Rozumiem przez to High cohesion, że powinniśmy mieć klasy wyspecjalizowane do wykonywania określonej funkcji. Mam nadzieję, że to prawda? Podobnie jak klasa weryfikacji kart kredytowych, która specjalizuje się tylko w sprawdzaniu poprawności kart kredytowych.

I nadal nie rozumiesz, co oznacza niskie sprzężenie?

user1315906
źródło
4
Aby uzyskać bardziej szczegółowe wyjaśnienie, możesz preferować odpowiedź z tego postu Spójność i łączenie
nieskończoność
Ta odpowiedź jest z pewnością lepsza i zwięzła niż te podane tutaj.
Lokesh
W rzeczywistości jest to ich duplikat. Odpowiedź Infinity jest jedyną nieuduplikowaną wersją, która nie została tutaj wymieniona.
cellepo

Odpowiedzi:

232

Wierzę w to:

Spójność odnosi się do stopnia, w jakim elementy modułu / klasy należą do siebie, sugeruje się, aby powiązany kod był blisko siebie, dlatego powinniśmy dążyć do wysokiej spójności i wiązać cały powiązany kod ze sobą jak najbliżej. Ma to związek z elementami w module / klasie.

Sprzężenie odnosi się do stopnia, w jakim różne moduły / klasy są od siebie zależne, sugeruje się, aby wszystkie moduły były jak najbardziej niezależne, dlatego też niskie sprzężenie. Ma do czynienia z elementami wśród różnych modułów / klas.

Wizualizacja całego obrazu będzie pomocna:

wprowadź opis obrazu tutaj

Zrzut ekranu pochodzi z Coursera .

vishal_aim
źródło
20
Nasz profesor mówi: „Wysoka spójność polega na upewnieniu się, że moduł nie robi wielu rzeczy, ma robić tylko jedną konkretną rzecz”.
Lokesh
2
Z tego, co uważam za bardziej podobne do „upewniania się, że jeden moduł robi coś, a niewiele modułów robi to samo”, dzięki temu można zapewnić, że tylko jeden moduł określa zachowanie, więc ogólne zachowanie rzeczy jest spójne.
sschrass
5
@Lokesh Myślę, że twój komentarz wszystko pogmatwa. Pani profesor myli wysoką spójność z „zasadą pojedynczej odpowiedzialności”. Wysoka spójność oznacza trzymanie razem podobnych i powiązanych rzeczy. Możesz mieć wysoką spójność w obiekcie lub usłudze, która składa się z wielu funkcji.
Max Hodges
17
Ten diagram dosłownie nic nie znaczy.
Liam
1
W kategoriach architektury mikroserwisów wysoka spójność oznacza, że ​​silnie powiązane rzeczy powinny być trzymane razem w jednej mikroserwisie, a luźne powiązanie oznacza, że ​​sama mikroserwis powinna być drobnoziarnista, aby działać w ograniczonym kontekście, tj. Robić jedną rzecz niezależnie.
sactiw
41

Spójność w inżynierii oprogramowania, podobnie jak w prawdziwym życiu, polega na tym, na ile elementów składających się na całość (w naszym przypadku powiedzmy klasę) można powiedzieć, że faktycznie należą do siebie. Jest to zatem miara tego, jak silnie powiązany jest każdy element funkcjonalności wyrażony w kodzie źródłowym modułu oprogramowania.

Jednym ze sposobów spojrzenia na spójność w kategoriach OO jest to, że metody w klasie używają któregokolwiek z atrybutów prywatnych.

Teraz dyskusja jest szersza, ale Wysoka spójność (lub najlepszy typ spójności - spójność funkcjonalna) ma miejsce, gdy części modułu są zgrupowane, ponieważ wszystkie przyczyniają się do jednego, dobrze zdefiniowanego zadania modułu.

Powiązanie w prostych słowach to, ile jeden składnik (ponownie wyobraź sobie klasę, chociaż niekoniecznie) wie o wewnętrznym działaniu lub elementach wewnętrznych innego składnika, tj. Ile ma wiedzy o drugim składniku.

Luźne sprzężenie to metoda łączenia elementów w systemie lub sieci, tak aby elementy te zależały od siebie w jak najmniejszym praktycznie możliwym zakresie…

Napisałem o tym wpis na blogu . Omawia to wszystko szczegółowo, z przykładami itp. Wyjaśnia również korzyści płynące z przestrzegania tych zasad.

TheBoyan
źródło
26

W projektowaniu oprogramowania wysoka spójność oznacza, że ​​klasa powinna robić jedną rzecz i jedną bardzo dobrze. Wysoka spójność jest ściśle związana z zasadą pojedynczej odpowiedzialności .

Niskie sprzężenie sugeruje, że klasa powinna mieć najmniej możliwych zależności. Zależności, które muszą istnieć, powinny być słabymi zależnościami - preferuj zależność od interfejsu zamiast zależności od konkretnej klasy lub preferuj kompozycję zamiast dziedziczenia.

Wysoka spójność i niskie sprzężenie dają nam lepiej zaprojektowany kod, który jest łatwiejszy w utrzymaniu.

zoran
źródło
Przegapiłeś Dependency Injection. Jest to ściśle związane z niskim sprzężeniem, aby zapewnić, że klasa ma najmniej zależności / żadnych zależności.
BugHunterUK
16

Krótka i jasna odpowiedź

  • Wysoka spójność : elementy w ramach jednej klasy / modułu powinny funkcjonalnie do siebie pasować i wykonywać jedną szczególną rzecz.
  • Luźne powiązanie : między różnymi klasami / modułami powinna występować minimalna zależność.
Daniel Perník
źródło
9

Niskie sprzężenie występuje w kontekście dwóch lub wielu modułów. Jeśli zmiana w jednym module powoduje wiele zmian w innym module, mówi się, że są one silnie powiązane. Tutaj pomaga programowanie oparte na interfejsach. Żadna zmiana w module nie wpłynie na inny moduł, ponieważ interfejs (średnia interakcji) między nimi nie uległ zmianie.

Wysoka spójność - Połącz podobne rzeczy. Tak więc klasa powinna mieć metodę lub zachowania do wykonania podobnej pracy. Żeby dać przesadny zły przykład: implementacja interfejsu List nie powinna mieć operacji związanej z ciągiem. Klasa String powinna mieć metody, pola, które są istotne dla String i podobnie implementacja List powinna mieć odpowiednie rzeczy.

Mam nadzieję, że to pomoże.

Braj Kishore
źródło
5

Krótko mówiąc, niskie sprzężenie, jak zrozumiałem, oznaczało, że komponenty można wymieniać bez wpływu na prawidłowe funkcjonowanie systemu. Zasadniczo moduluj swój system w działające komponenty, które można aktualizować indywidualnie bez uszkadzania systemu

Wonderwall
źródło
1
Czy to nie to samo, co Wysoka spójność?
user1315906
4

Masz smartphona? Czy jest jedna duża aplikacja lub wiele małych? Czy jedna aplikacja odpowiada na inną? Czy możesz używać jednej aplikacji podczas instalowania, aktualizowania i / lub odinstalowywania innej? To, że każda aplikacja jest samodzielna, zapewnia dużą spójność. To, że każda aplikacja jest niezależna od innych, jest niskim sprzężeniem. DevOps preferuje tę architekturę, ponieważ oznacza to, że można wykonywać dyskretne ciągłe wdrażanie bez zakłócania całego systemu.

Clarius
źródło
> Czy jedna aplikacja odpowiada na inną? . . cóż, tak, niektórzy tak. Wiele aplikacji korzysta z aplikacji Aparat, dzięki której aplikacja treningowa przekazuje dane dotyczące serca i treningu do Zdrowia i Aktywności. Mogę udostępnić fragment z jednej aplikacji wielu innym. Moja aplikacja alarmowa zna godzinę i odtwarza utwór z aplikacji Muzyka ...
Max Hodges
@MaxHodges to (niska spójność i wysokie sprzężenie) jest amortyzowane i powinno być zminimalizowane w jak najmniejszym stopniu. W niektórych przypadkach, jak wspomniałeś. Nie można tego całkowicie usunąć.
M. Habib,
2

Dziedziczenie lub uogólnienie jest przykładem wysokiego sprzężenia (tj. Dużej współzależności). Miałem na myśli to, że w dziedziczeniu często klasa nadrzędna definiuje podstawowe funkcje, które są używane przez jej klasę potomną, a zmiana metod klasy nadrzędnej bezpośrednio wpływa na jej klasy potomne. Dlatego możemy powiedzieć, że istnieje większy stopień współzależności między klasami.

Realizacja lub wykorzystanie interfejsu jest przykładem wysokiej spójności (tj. Małej współzależności). Oznacza to, że interfejs przedstawił kontrakt dla dowolnej klasy, która go implementuje, ale każda klasa ma prawo implementować metody zadeklarowane w interfejsie na swój własny sposób, a zmiany metody zadeklarowanej w jednej klasie nie wpływają na żadną inną.

Varun
źródło
2

Spójność - jak ściśle wszystko jest ze sobą powiązane.
Sprzęganie - jak wszystko jest ze sobą połączone.

Weźmy przykład - chcemy zaprojektować samochód autonomiczny.

(1) Silnik musi działać prawidłowo.

(2) Potrzebujemy samochodu do samodzielnej jazdy.

Wszystkie klasy i funkcje w (1) uruchamianiu silnika i sprawianiu, by działał świetnie ze sobą współpracują, ale nie pomagają w kierowaniu samochodem. Dlatego umieszczamy te klasy za kontrolerem silnika.

Wszystkie klasy i funkcje w (2) działają świetnie, aby samochód sterował, przyspieszał i hamował. Nie pomagają uruchomić samochodu ani nie wysyłają benzyny do tłoków. Dlatego umieszczamy te klasy za własnym kontrolerem jazdy.

Te kontrolery służą do komunikacji ze wszystkimi dostępnymi klasami i funkcjami. Kontrolery komunikują się wtedy tylko ze sobą. Oznacza to, że nie mogę wywołać funkcji z klasy tłoków z klasy pedału gazu, aby samochód jechał szybciej.

Klasa pedałów musi poprosić kontrolera jazdy, aby porozmawiał z kontrolerem silnika, który następnie powie klasie tłoków, aby jechali szybciej. Dzięki temu programiści mogą znajdować problemy i bez obaw łączyć duże programy. Dzieje się tak, ponieważ cały kod działał za kontrolerem.

CardCastle Studio
źródło
1

Zalecane są niskie sprzężenie i wysoka kohezja.

Sprzężenie oznacza, w jakim stopniu różne moduły są współzależne i jaki wpływ na inne moduły mają zmiana części / znacznej funkcjonalności modułu. Podkreśla się niskie sprzężenie, ponieważ zależność musi być utrzymywana na niskim poziomie, aby w innych modułach wprowadzano najmniejsze / nieistotne zmiany.

kmario23
źródło
1

Przykład może być pomocny. Wyobraź sobie system, który generuje dane i umieszcza je w magazynie danych, albo w pliku na dysku, albo w bazie danych.

Wysoką spójność można osiągnąć, oddzielając kod magazynu danych od kodu generującego dane. (a właściwie oddzielenie pamięci dyskowej od przechowywania bazy danych).

Niskie sprzężenie można osiągnąć, upewniając się, że wytwarzanie danych nie ma niepotrzebnej wiedzy o magazynie danych (np. Nie pyta magazynu danych o nazwy plików lub połączenia db).

Ashirley
źródło
1

Oto odpowiedź z nieco abstrakcyjnego, teoretycznego kąta wykresu:

Uprośćmy problem, patrząc tylko na (ukierunkowane) wykresy zależności między obiektami stanowymi.

Niezwykle prostą odpowiedź można zilustrować, rozważając dwa graniczne przypadki wykresów zależności:

Pierwszy przypadek graniczny : wykresy skupień .

Graf skupień jest najdoskonalszą realizacją wykresu zależności o wysokiej spójności i niskim sprzężeniu (biorąc pod uwagę zestaw rozmiarów klastrów).

Zależność między klastrami jest maksymalna (w pełni połączone), a zależność między klastrami jest minimalna (zero).

To jest abstrakcyjna ilustracja odpowiedzi w jednym z ograniczających przypadków .

Drugi przypadek ograniczający to w pełni połączony wykres, w którym wszystko zależy od wszystkiego.

Rzeczywistość jest gdzieś pomiędzy, im bliżej wykresu skupień, tym lepiej, w moim skromnym rozumieniu.

Z innego punktu widzenia : patrząc na wykres zależności ukierunkowanej, najlepiej powinien być acykliczny, jeśli nie, to cykle tworzą najmniejsze skupienia / komponenty.

Jeden krok w górę / w dół w hierarchii odpowiada „jednej instancji” luźnego sprzężenia, ścisłej spójności w oprogramowaniu, ale można postrzegać tę zasadę luźnego sprzężenia / ścisłej kohezji jako powtarzające się zjawisko na różnych głębokościach acyklicznego wykresu skierowanego (lub na jeden z jego drzew rozpinających).

Taka dekompozycja systemu na hierarchię pomaga pokonać wykładniczą złożoność (powiedzmy, że każdy klaster ma 10 elementów). Następnie przy 6 warstwach to już 1 milion obiektów:

10 gromad tworzy 1 supergromadę, 10 supergromad tworzy 1 hipergromadę i tak dalej ... bez koncepcji ścisłej spójności, luźnego sprzężenia, taka hierarchiczna architektura nie byłaby możliwa.

Może to być więc prawdziwe znaczenie tej historii, a nie tylko sprzężenie o wysokiej spójności i niskim sprzężeniu tylko w dwóch warstwach. Prawdziwe znaczenie staje się jasne, gdy rozważa się abstrakcje wyższego poziomu i ich interakcje.

jhegedus
źródło
0

Myślę, że masz tyle definicji na czerwono, ale jeśli nadal masz wątpliwości lub jeśli jesteś nowy w programowaniu i chcesz zagłębić się w to, zasugeruję obejrzenie tego filmu, https://youtu.be/HpJTGW9AwX0 To tylko odniesienie, aby uzyskać więcej informacji o polimorfizmie ... Mam nadzieję, że lepiej to zrozumiesz

Nikhil Bhardwaj
źródło
0

Niskie sprzęgło: - To bardzo proste. Jeśli zmienisz swój moduł, jak to wpłynie na inne moduły.

Przykład: - Jeśli API usługi jest ujawnione jako JAR, każda zmiana w sygnaturze metody spowoduje przerwanie wywoływania API (połączenie typu High / Tight).

Jeśli Twój moduł i inny moduł komunikują się za pomocą komunikatów asynchronicznych. Dopóki otrzymujesz komunikaty, sygnatura zmiany metody będzie lokalna dla Twojego modułu (niskie sprzężenie).

Oczywiście, jeśli nastąpi zmiana w formacie wiadomości, klient dzwoniący będzie musiał dokonać pewnych zmian.

Abhishek Shinde
źródło