Качественный дизайн обладает слабой связанностью (low coupling) и сильной связностью (high cohesion).
Это значит, что программный компонент имеет небольшое число внешних связей и отвечает за решение близких по смыслу задач.
Связанность (Coupling)
Связанность, сопряжение (coupling)— способ и степень взаимозависимости между программными модулями; сила взаимосвязей между модулями; мера того, насколько взаимозависимы разные подпрограммы или модули.
Сильная связанность (High coupling) рассматривается как серьёзный недостаток, поскольку затрудняет понимание логики модулей, их модификацию, автономное тестирование, а также переиспользование по отдельности.
Слабая связанность (Low coupling), напротив, является признаком хорошо структурированной и хорошо спроектированной системы, и, когда она комбинируется с сильной связностью(high cohesion), соответствует общим показателям хорошей читаемости и сопровождаемости.
Low Coupling — это принцип, который позволяет распределить обязанности между объектами таким образом, чтобы степень связанности между системами оставалась низкой.
Степень связанности (coupling) — это мера, определяющая, насколько жестко один элемент связан с другими элементами, либо каким количеством данных о других элементах он обладает.
Элемент с низкой степенью связанности (или слабым связыванием) зависит от не очень большого числа других элементов и имеет следующие свойства:
- Малое число зависимостей между классами (подсистемами).
- Слабая зависимость одного класса (подсистемы) от изменений в другом классе (подсистеме).
- Высокая степень повторного использования подсистем.
Виды связанности
Связанность содержимого (content coupling)
- Один модуль изменяет или полагается на внутренние особенности другого модуля (например, использует локальные данные другого модуля)
- Изменение работы второго модуля приведет к переписыванию первого
Связанность через общее (common coupling)
- Два модуля работают с общими данными (например, глобальной переменной)
- Изменение разделяемого ресурса приведет к изменению всех работающих с ним модулей
Связанность через внешнее (external coupling)
- Два модуля используют навязанный извне формат данных, протокол связи и т.д.
- Обычно возникает из-за внешних сущностей (инструментов, устройств и т.д.)
Связанность по управлению (control coupling)
- Один модуль управляет поведением другого
- Присутствует передача информации о том, что и как делать
Связанность по структурированным данным (data-structured coupling, stamp couplig)
- Модули используют одну и ту же структуру, но каждый использует только ее части
- Изменение структуры может привести к изменению модуля, который измененную часть даже не использует
Связанность через данных (data coupling)
- Модули совместно используют данные, например, через параметры
- Элементарные фрагменты маленькие и только они используются модулями совместно
Связанность по сообщениям (message coupling)
- Модули общаются только через передачу параметров или сообщений
- Состояние децентрализовано
Отсутствие связанности (no coupling)
- Модули вообще никак не взаимодействуют
Закон Деметры
Принцип наименьшего знания
Закон Деметры (Law of Demeter, LoD) — набор правил проектирования при разработке программного обеспечения, в частности объектно-ориентированных программ, накладывающий ограничения на взаимодействия объектов (модулей).
Обобщенно, закон Деметры является специальным случаем слабой связанности (loose coupling). Правила были предложены в конце 1987 в северо-восточном Университете (Бостон, Массачусетс, США).
Говоря упрощённо, каждый программный модуль:
- должен обладать ограниченным знанием о других модулях: знать о модулях, которые имеют «непосредственное» отношение к этому модулю.
- должен взаимодействовать только с известными ему модулями «друзьями», не взаимодействовать с незнакомцами.
- обращаться только к непосредственным «друзьям».
Общее описание правила: Объект A не должен иметь возможность получить непосредственный доступ к объекту C, если у объекта A есть доступ к объекту B и у объекта B есть доступ к объекту C.
Таким образом, код a.b.Method() нарушает Закон Деметры, а код a.Method() является корректным.
Преимущества
Преимуществами закона Деметры является то, что код, разработанный с соблюдением данного закона, делает написание тестов более простым, а разработанное программное обеспечение менее сложно при поддержке и имеет большие возможности повторного использования кода. Так как объекты являются менее зависимыми от внутренней структуры других объектов, контейнеры объектов могут быть изменены без модификации вызывающих объектов (клиентов).
Недостатки
Недостатком закона Деметры является то, что иногда требуется создание большого количества малых методов-адаптеров (делегатов) для передачи вызовов метода к внутренним компонентам.
Связность (Cohesion)
Связность, или прочность (cohesion) — мера силы взаимосвязанности элементов внутри модуля; способ и степень, в которой задачи, выполняемые некоторым программным модулем, связаны друг с другом.
Cвязность характеризует то, насколько хорошо все методы класса или все фрагменты метода соответствуют главной цели, — иначе говоря, насколько сфокусирован класс. Стив Макконнелл
Считается, что объект (подсистема) обладает высокой связностью (High cohesion), если его обязанности хорошо согласованы между собой и он не выполняет огромных объемов работы.
Класс с низкой связностью(low cohesion) выполняет много разнородных функций или несвязанных между собой обязанностей. Такие классы создавать нежелательно, поскольку они приводят к возникновению следующих проблем:
- Трудность понимания
- Сложность при повторном использовании
- Сложность поддержки
- Ненадежность, постоянная подверженность изменениям
Классы с низкой степенью связности, как правило, являются слишком «абстрактными» или выполняют обязанности, которые можно легко распределить между другими объектами.
Виды связности
Случайная (coincidental cohesion)
- Части модуля сгруппированы “от фонаря”
- Единственное, что их объединяет — сам модуль
Логическая (logical cohesion)
- Части модуля логически относятся к одной проблеме
- При этом части могут различаться по своей природе
Временная (temporal cohesion)
- Части модуля обычно используются в программе в одно время, рядом
Процедурная (procedural cohesion)
- Части модуля всегда используются в определенном порядке
По взаимодействию (communication cohesion)
- Части модуля работают над одним и теми же данными
По последовательности действий (sequential cohesion)
- Результат работы одной части модуля является исходными данными для другой
Функциональная (functional cohesion)
- Части модуля направлены на решение одной четкой задачи, за которую отвечает модуль
RTFM
Источник: Low Coupling и High Cohesion (German Gorelkin)
Источник: https://www.kobzarev.com/programming/low-coupling-i-high-cohesion/