Разница между сцеплением и сцеплением

486

В чем разница между сцеплением и сцеплением?

Как связывание и сплоченность могут привести к хорошему или плохому дизайну программного обеспечения?

Какие примеры иллюстрируют разницу между ними и их влияние на общее качество кода?

JavaUser
источник
2
проверить это: msdn.microsoft.com/en-us/magazine/cc947917.aspx
Inv3r53
3
Я хотел бы указать на эту статью: Разработка программного обеспечения SOLID, один шаг за раз . Grz, Крис.
Крис ван дер Маст
4
Это последнее сообщение на эту тему
Janisz
2
Смотрите также: stackoverflow.com/questions/39946/coupling-and-cohesion
davidpricedev

Ответы:

703

Сплоченность относится к тому, что может сделать класс (или модуль). Низкая сплоченность означала бы, что класс совершает самые разные действия - он широкий, не сфокусированный на том, что он должен делать. Высокая сплоченность означает, что класс ориентирован на то, что он должен делать, то есть только на методы, относящиеся к намерению класса.

Пример низкой когезии:

-------------------
| Staff           |
-------------------
| checkEmail()    |
| sendEmail()     |
| emailValidate() |
| PrintLetter()   |
-------------------

Пример высокой когезии:

----------------------------
| Staff                   |
----------------------------
| -salary                 |
| -emailAddr              |
----------------------------
| setSalary(newSalary)    |
| getSalary()             |
| setEmailAddr(newEmail)  |
| getEmailAddr()          |
----------------------------

Что касается связи , это относится к тому, как два родственных класса или модуля связаны друг с другом. Для классов с низкой связью изменение чего-то важного в одном классе не должно влиять на другой. Высокая связь затруднит изменение и поддержку вашего кода; поскольку классы тесно связаны, для внесения изменений может потребоваться полная модернизация системы.

Хороший программный дизайн имеет высокую когезию и низкую связь .

mauris
источник
12
Я не вижу, как удаление нескольких методов и добавление нескольких других повышает сплоченность. Может кто-нибудь помочь здесь, пожалуйста?
Сакет Джайн
3
@SaketJain - это не просто удаление некоторых методов и добавление других. это то, как методы связаны с назначением класса (если это объяснение яснее).
Mauris
4
пример низкой сплоченности наверху выглядит довольно хорошо, я думаю, вы случайно хотели сказать «высокая сплоченность»
переиздание
37
@SaketJain Класс персонала - это не то место, где мы проверяем, отправляем или проверяем электронную почту. Эти функции должны входить в гипотетический класс электронной почты, поэтому его низкая сплоченность. Во втором примере класс Staff содержит только правильную информацию для настройки и получения данных, связанных с персоналом. Они не выполняют действия, которыми должен управлять другой класс.
Антонио Пантано
3
@JonathanC примеры не должны доказывать разницу (как в математическом доказательстве), чтобы все еще быть примером. Не стесняйтесь отвечать или комментировать любые примеры, которые вы считаете более полезными. Функции set& getиллюстрируют функциональность, которая более специфична для контекста «персонала» - чем выше специфичность, тем выше сплоченность.
виолончель
81

Сплоченность является показателем отношений внутри модуля.

Связь является показателем взаимосвязей между модулями.

введите описание изображения здесь

когезия

  • Сплоченность является показателем взаимосвязи внутри модуля.
  • Сплоченность показывает относительную функциональную прочность модуля.
  • Сплоченность - это степень (качество), в которой компонент / модуль фокусируется на одной вещи.
  • При проектировании вы должны стремиться к высокой сплоченности, то есть к единому компоненту / модулю, сосредоточенному на одной задаче (т. Е. Нацеленности), с небольшим взаимодействием с другими модулями системы.
  • Сплоченность - это естественное расширение, например, скрытие данных, когда в классе все члены видны, а пакет имеет видимость по умолчанию. Сплоченность - это внутримодульная концепция.

Связь

  • Связь является показателем взаимосвязей между модулями.
  • Связь показывает относительную зависимость / взаимозависимость между модулями.
  • Соединение - это степень, в которой компонент / модуль связан с другими модулями.
  • При проектировании вы должны стремиться к низкой связи, т.е. зависимость между модулями должна быть меньше
  • Создание приватных полей, приватных методов и непубличных классов обеспечивает слабую связь.
  • Муфта - это межмодульная концепция.

проверьте эту ссылку

Буддика Алвис
источник
77

Высокая когезия внутри модулей и низкая связь между модулями часто рассматриваются как связанные с высоким качеством в языках программирования ОО.

Например, код внутри каждого Java-класса должен иметь высокую внутреннюю сплоченность, но быть как можно слабее связанным с кодом в других Java-классах.

Глава 3 « Создание объектно-ориентированного программного обеспечения» Мейера (2-е издание) - отличное описание этих проблем.

CesarGon
источник
3
Концепции не ограничиваются ОО-программированием. Во всяком случае, я бы предположил, что цель ОО-языков состоит в том, чтобы направить программиста к целям высокой сплоченности / слабой связи.
Хатч
57

Сплоченность является показателем того, насколько связаны и сфокусированы обязанности программного элемента.

Связность означает, насколько сильно программный элемент связан с другими элементами.

Программный элемент может быть классом, пакетом, компонентом, подсистемой или системой. И при проектировании систем рекомендуется иметь программные элементы, которые имеют высокую когезию и поддерживают низкую связь .

Низкая когезия приводит к монолитным классам, которые трудно поддерживать, понимать и уменьшает повторное использование. Точно так же высокая связь приводит к тому, что классы тесно связаны, и изменения, как правило, не являются нелокальными, их трудно изменить, и это уменьшает повторное использование.

Мы можем принять гипотетический сценарий, в котором мы разрабатываем типичный монитор ConnectionPoolс учетом следующих требований. Обратите внимание, что для простого класса это может выглядеть слишком много, ConnectionPoolно основная цель - просто продемонстрировать слабую связь и высокую сплоченность с помощью некоторого простого примера, и я думаю, что это должно помочь.

  1. поддержка получения соединения
  2. освободить связь
  3. получить статистику о соединении в сравнении с использованием счетчика
  4. получить статистику о времени соединения
  5. Сохраните поиск соединения и передайте информацию в базу данных для последующего отчета.

При низкой сплоченности мы могли бы спроектировать ConnectionPoolкласс, принудительно сложив все эти функции / обязанности в один класс, как показано ниже. Мы видим, что этот единственный класс отвечает за управление соединением, взаимодействие с базой данных, а также за поддержание статистики соединения.

Бассейн с низкой когезией

С высокой степенью сплоченности мы можем распределить эти обязанности между классами и сделать их более ремонтопригодными и пригодными для повторного использования.

Бассейн с высокой когезией

Чтобы продемонстрировать низкую связь, мы продолжим с ConnectionPoolдиаграммой высокой когезии выше. Если мы посмотрим на диаграмму выше, хотя она поддерживает высокую степень сцепления, ConnectionPoolона тесно связана с ConnectionStatisticsклассом и PersistentStoreвзаимодействует с ними напрямую. Вместо этого, чтобы уменьшить связь, мы могли бы ввести ConnectionListenerинтерфейс и позволить этим двум классам реализовать интерфейс и позволить им зарегистрироваться в ConnectionPoolклассе. И он ConnectionPoolбудет перебирать этих слушателей и уведомлять их о событиях получения и освобождения соединения и позволяет меньше связывать.

Соединение для низкого соединения

Примечание / слово или предостережение: для этого простого сценария это может выглядеть излишним, но если мы представим сценарий в реальном времени, в котором нашему приложению необходимо взаимодействовать с несколькими сторонними сервисами для завершения транзакции: напрямую связывая наш код со сторонними сервисами будет означать, что любые изменения в сторонней службе могут привести к изменениям в нашем коде в нескольких местах, вместо этого мы могли бы иметь, Facadeчто взаимодействует с этими несколькими службами внутри, и любые изменения в службах становятся локальными для Facadeи обеспечивают низкую связь с третьей стороной Сервисы.

Мадхусудана Редди Суннапу
источник
3
Отличный ответ! Если возможно, не могли бы вы использовать другой пример? Пул соединений может быть понятен не всем. Несмотря на это, это действительно помогло мне. Тогда спасибо!
Сакет Джейн
Как использование интерфейса ConnectionListener помогает уменьшить сцепление? Можете ли вы привести пример, который легче понять?
Абхишек Гупта
1
@abhishekgupta В этом примере вы могли заметить, что мы использовали шаблон наблюдателя для достижения низкого / слабого соединения. Это поможет, как Observer создаст слабосвязанный дизайн?
Мадхусудана Редди Суннапу
33

Увеличенная когезия и уменьшенная связь приводят к хорошему дизайну программного обеспечения.

Сплоченность разделяет вашу функциональность так, чтобы она была краткой и максимально приближенной к данным, относящимся к ней, в то время как разделение гарантирует, что функциональная реализация изолирована от остальной части системы.

Разъединение позволяет вам изменять реализацию, не затрагивая другие части вашего программного обеспечения.

Сплоченность гарантирует, что реализация более специфична для функциональности и в то же время проще в обслуживании.

Наиболее эффективным методом уменьшения сцепления и увеличения сцепления является проектирование по интерфейсу .

То есть основные функциональные объекты должны «знать» друг друга только через интерфейс (ы), который они реализуют. Реализация интерфейса представляет единство как естественное следствие.

Хотя это нереально в некоторых случаях, это должно быть целью разработки.

Пример (очень схематично):

public interface IStackoverFlowQuestion
      void SetAnswered(IUserProfile user);
      void VoteUp(IUserProfile user);
      void VoteDown(IUserProfile user);
}

public class NormalQuestion implements IStackoverflowQuestion {
      protected Integer vote_ = new Integer(0);
      protected IUserProfile user_ = null;
      protected IUserProfile answered_ = null;

      public void VoteUp(IUserProfile user) {
           vote_++;
           // code to ... add to user profile
      }

      public void VoteDown(IUserProfile user) {
          decrement and update profile
      }

      public SetAnswered(IUserProfile answer) {
           answered_ = answer
           // update u
      }
}

public class CommunityWikiQuestion implements IStackoverflowQuestion {
     public void VoteUp(IUserProfile user) { // do not update profile }
     public void VoteDown(IUserProfile user) { // do not update profile }
     public void SetAnswered(IUserProfile user) { // do not update profile }
}

Где-то еще в вашей кодовой базе вы можете иметь модуль, который обрабатывает вопросы независимо от того, что они из себя представляют:

public class OtherModuleProcessor {
    public void Process(List<IStackoverflowQuestion> questions) {
       ... process each question.
    }
}
Адриан Риган
источник
28

лучшее объяснение сплоченности исходит из чистого кода дяди Боба:

Классы должны иметь небольшое количество переменных экземпляра. Каждый из методов класса должен манипулировать одной или несколькими из этих переменных. В общем, чем больше переменных, которыми манипулирует метод, тем более сплоченным является метод для своего класса . Класс, в котором каждая переменная используется каждым методом, является максимально связным.

В общем случае нецелесообразно и невозможно создать такие максимально сплоченные классы; с другой стороны, мы бы хотели, чтобы сплоченность была высокой . Когда сплоченность высока, это означает, что методы и переменные класса являются взаимозависимыми и объединяются как логическое целое.

Стратегия сохранения небольших функций и сокращения списков параметров иногда может привести к увеличению количества переменных экземпляра, которые используются подмножеством методов. Когда это происходит, это почти всегда означает, что есть хотя бы один другой класс, пытающийся выбраться из более крупного класса. Вы должны попытаться разделить переменные и методы на два или более классов, чтобы новые классы были более связными.

Кэтэлин Рэдой
источник
Я согласен, что это, вероятно, лучшее объяснение, это то, что мне нравится в дяде Бобе, что он может объяснить действительное значение в нескольких фразах. Зная это определение, вы можете сразу увидеть, что нужно сделать с данным классом, чтобы повысить его сплоченность.
Павел Дубиль
13

просто, Cohesion представляет степень, в которой часть базы кода формирует логически единую атомарную единицу. Соединение , с другой стороны, представляет степень, в которой одна единица независима от других. Другими словами, это количество соединений между двумя или более устройствами. Чем меньше число, тем ниже муфта.

По сути, высокая сплоченность означает хранение частей базы кода, которые связаны друг с другом, в одном месте. Слабая связь, в то же время, заключается в том, чтобы максимально разделить несвязанные части кодовой базы.

Типы кода с точки зрения сплоченности и связи:

Идеальным является код, который следует руководящим принципам. Это слабосвязанный и очень сплоченный. Мы можем проиллюстрировать такой код этой картинкой:введите описание изображения здесь

Объект Бога является результатом введения высокой сплоченности и высокой связи. Это анти-шаблон и в основном означает один кусок кода, который выполняет всю работу одновременно: плохо выбранный происходит, когда границы между различными классами или модулями выбраны плоховведите описание изображения здесь введите описание изображения здесь

Разрушительная развязка - самая интересная. Иногда это происходит, когда программист пытается настолько отделить кодовую базу, что код полностью теряет фокус:введите описание изображения здесь

читайте больше здесь

Алиреза Рахмани Халили
источник
1
Отличная статья и иллюстрации! Если я могу предложить улучшение только одной мысли, мне нравится, как «плохо выбранный» удерживает группы компонентов с несвязанной семантикой в ​​небольших скоплениях, но я думаю, что между ними должно быть заметно больше стрелок. В конце концов, даже на ваших графиках с 4 квадратами это тот, который попадает в верхний диапазон оси «Связи».
Славомир Бжезинский
1
Я также сказал бы, что у «плохо отобранных» должно быть меньше стрелок в каждом рое. Использование примера «структуры папок» из вашей статьи, который вы классифицируете как «плохо отобранные» репозитории или фабрики, определенно не будет общаться друг с другом.
Славомир Бжезинский
ОБНОВЛЕНИЕ: я поднял эти предложения к первоначальному автору изображения, и автор согласился с ними .
Славомир Бжезинский
11

Сплоченность в разработке программного обеспечения - это степень, в которой элементы определенного модуля принадлежат друг другу. Таким образом, это мера того, насколько тесно связана каждая часть функциональности, выраженная в исходном коде программного модуля.

Связывание в простых словах - это то, сколько один компонент (опять же, представьте себе класс, хотя и не обязательно) знает о внутренней работе или внутренних элементах другого, то есть, сколько он знает о другом компоненте.

Я написал сообщение в блоге об этом , если вы хотите прочитать немного подробнее с примерами и рисунками. Я думаю, что это отвечает на большинство ваших вопросов.

TheBoyan
источник
5

введите описание изображения здесь

Сплоченность относится все о том, как разработан один класс. Сплоченность - это объектно-ориентированный принцип, наиболее тесно связанный с обеспечением того, чтобы класс был разработан с единственной, четко сфокусированной целью. Чем более сфокусирован класс, тем больше сплоченность этого класса. Преимущества высокой когезии состоят в том, что такие классы гораздо легче поддерживать (и реже менять), чем классы с низкой когезией. Еще одним преимуществом высокой сплоченности является то, что классы с четко определенной целью, как правило, более пригодны для повторного использования, чем другие классы.

На изображении выше мы видим, что при низкой когезии только один класс отвечает за выполнение множества не общих задач, что снижает вероятность повторного использования и обслуживания. Но в высокой степени сплоченности существует отдельный класс для всех заданий, выполняющих определенное задание, что повышает удобство использования и обслуживания.

vkstream
источник
2

Сплоченность (Co-hesion): Co, что означает вместе , hesion, что означает придерживаться . Система склеивания частиц разных веществ.

Для примера из жизни: img Courtesy
введите описание изображения здесь

Целое больше, чем сумма частей - Аристотель.

  • Сплоченность является порядковым типом измерения и обычно описывается как «высокая когезия» или «низкая когезия». Модули с высокой когезией имеют тенденцию быть предпочтительными, потому что высокая когезия связана с несколькими желательными характеристиками программного обеспечения, включая надежность, надежность, возможность повторного использования и понятность. Напротив, низкая когезия связана с нежелательными чертами, такими как трудность в обслуживании, тестировании, повторном использовании или даже понимании. вики

  • Сцепление обычно противопоставляется сплоченности . Низкая связь часто коррелирует с высокой когезией, и наоборот. Низкая связь часто является признаком хорошо структурированной компьютерной системы и хорошего дизайна, а в сочетании с высокой связностью поддерживает общие цели высокой читаемости и удобства обслуживания. вики

Premraj
источник
1

Я думаю, что различия могут быть изложены следующим образом:

  • Сплоченность представляет степень, в которой часть кодовой базы образует логически единичную атомарную единицу.
  • Связь представляет собой степень, в которой один блок независим от других.
  • Невозможно заархивировать полную развязку без ущерба для сплоченности, и наоборот.

В этом посте я пишу об этом более подробно.

Владимир
источник
1

Сплоченность является показателем относительной функциональной прочности модуля.

  • Связанный модуль выполняет единственную задачу, требующую небольшого взаимодействия с другими компонентами в других частях программы. Проще говоря, связующий модуль должен (в идеале) делать только одну вещь.
  • View Традиционный вид:

    «целеустремленность» модуля

  • ViewOO вид:

    Единство подразумевает, что компонент или класс инкапсулируют только те атрибуты и операции, которые тесно связаны друг с другом и с классом или самим компонентом.

  • EУровни сплоченности

    Functional

    Layer

    Communicational

    Sequential

    Procedural

    Temporal

    utility

Связь является показателем относительной взаимозависимости между модулями.

  • Связь зависит от сложности интерфейса между модулями, точки, в которой делается запись или ссылка на модуль, и от того, какие данные передаются через интерфейс.

  • Обычное представление: степень, в которой компонент связан с другими компонентами и с внешним миром

  • OO view: качественная мера степени, в которой классы связаны друг с другом

  • Уровень сцепления

    Content

    Common

    Control

    Stamp

    Data

    Call Обычный звонок

    UseТип использования

    OrВключение или импорт

    TernalВнешний #

зет
источник
1

Связь = взаимодействие / отношения между двумя модулями ... Сплоченность = взаимодействие между двумя элементами внутри модуля.

Программное обеспечение состоит из множества модулей. Модуль состоит из элементов. Рассмотрим модуль как программу. Функция в программе - это элемент.

Во время выполнения вывод программы используется как ввод для другой программы. Это называется взаимодействием модуля с модулем или процессом обработки взаимодействия. Это также называется сцеплением.

В пределах одной программы вывод функции передается другой функции. Это называется взаимодействием элементов внутри модуля. Это также называется сплоченностью.

Пример:

Связь = общение между двумя разными семьями ... Сплоченность = общение между отцом, матерью и ребенком в семье.

Дипанкар Налуй
источник
1
Итак, как вы объясните их в контексте их влияния на программное обеспечение?
Итбан Саид
Программное обеспечение состоит из множества модулей. Модуль состоит из элементов. Рассмотрим модуль как программу. Функция в программе - это элемент.
Дипанкар Налуй
1

Проще говоря, сплоченность означает, что класс должен представлять единую концепцию.

Открытый интерфейс класса является связным, если все функции класса связаны с концепцией, которую представляет класс. Например, вместо того, чтобы иметь класс CashRegister, наличие единства функций CashRegister и Coin превращает его в 2 класса - класс CashRegister и Coin.

В соединении один класс зависит от другого, поскольку он использует объекты класса.

Проблема с высокой связью в том, что она может создавать побочные эффекты. Одно изменение в одном классе может вызвать неожиданную ошибку в другом классе и может привести к поломке всего кода.

Как правило, высокая когезия и низкая связь считается высоким качеством ООП.

Варун Джоши
источник
0

Термин сплоченность действительно немного противоречит тому, что он означает в разработке программного обеспечения.

Общим смыслом сплоченности является то, что что-то, что хорошо слипается, объединяется и характеризуется сильной связью, такой как молекулярное притяжение. Однако в разработке программного обеспечения это означает стремление к классу, который в идеале делает только одну вещь, поэтому несколько подмодулей даже не задействованы.

Возможно, мы можем думать об этом таким образом. Часть имеет наибольшую сплоченность, когда она единственная (выполняет только одну функцию и не может быть разбита дальше). Это то, что желательно в разработке программного обеспечения. Сплоченность - это просто другое название для «единой ответственности» или «разделения интересов».

Термин « связывание» на руке достаточно интуитивен, что означает, что когда модуль не зависит от слишком большого количества других модулей и те, с которыми он соединяется, могут быть легко заменены, например, следуя принципу подстановки Лискова .

зар
источник
Почему люди продолжают использовать слово модуль вместо класса?
северянин
1
@northerner это просто более общий термин.
Зар
0

Теория Разница

когезия

  • Сплоченность является показателем относительной функциональной прочности модуля.
  • Связанный модуль выполняет единственную задачу, требующую небольшого взаимодействия с другими компонентами в других частях программы.
  • Модуль, имеющий высокую когезию и низкую связь, называется функционально независимым от другого модуля.

Классификация сплоченности

1. Случайное 2. Логическое 3. Временное 4. Процедурное 5. Связь 6. Последовательное 7. Функциональное

Связь

  • Связь является показателем относительной взаимозависимости между модулями.
  • Степень связи между двумя модулями зависит от сложности их интерфейса.
КАРШИЛЬ ШЕТ
источник