Loose coupling
Если код программы не разделять на отдельные модули то он становится похожим на тарелку спагетти - извилистым и запутанным, такая программа может очень хорошо работать, но вот чинить её или добавлять новые функции в такую кашу занятие неблагодарное.
Тут на помощь приходит принцип "разделяй и властвуй". (Separation of Concerns SoC)
Гораздо удобнее иметь дело с кодом который выглядит как лего - набор отдельных модулей которые соединены друг с другом штекерами, это даёт ряд преимуществ:
- Ремонтопригодность (Maintainability)
изменение одного модуля не потребуют изменения других модулей
- Заменимость модулей (Swappability)
модуль легко заменить на другой, важно только чтобы пазы на деталях совпали
- Масштабируемость (Scalability)
добавляя новый модуль не нужно вникать во внутреннее устройство других модулей
- Возможность тестирования (Unit Testing)
модуль можно отсоединить от всех остальных и протестировать / починить
Ценой за эти удобства является необходимость писать больше кода (тратить больше времени) описывающего взаимосвязи модулей.
Поэтому, при проектировании крупных приложений, на вопрос "Спагетти или Модульность?" ответ очевиден.
Звучит всё замечательно, но есть подвох, очень часто оказывается, что модулю для выполнения своих функций нужно уметь общаться с большим количеством других модулей 5-10-20, причём расположенных не только по соседству, для общения с каждым отдельным модулем мы добавляем новый разъём и начинаем использовать шнуры для связи с дальними модулями. Спустя некоторые время оказывается, что мы опять имеем дело с тарелкой спагетти, только на этот раз это узел из шнуров, связывающих независимые модули.
Как же не запутаться в проводах?
Об этом я и хочу написать.
Для начал термины:
Зависимость (dependency) – знание одного модуля о другом
Связанность (coupling) — характеристика взаимосвязи модуля с другими модулями. Это степень, в которой каждый программный модуль зависит от других модулей.
Decoupling противоположность связанности — степень независимости модулей друг от друга.
Чем слабее связанность, тем лучше, тем легче понимать/расширять/чинить программу.
Итак, что может ослабить связанность модулей:
1 Создание зависимостей
Крайне важно то, как создаётся зависимость, то откуда зависящий модуль раздобывает ссылку на модуль, от которого он зависит. (Перечислять способы создания зависимостей и сравнивать их, тянет на тему для отдельной статьи, поэтому я не буду сейчас вдаваться в подробности). Самый гибкий подход это избавить модуль от необходимости заботится об этом вообще. Такой подход называется инверсия контроля (inversion of control, IoC). Один из способов внедрить принцип инверсии контроля, это использовать паттерн Dependency Injection. Инвертируется процесс создания зависимости, вместо самого модуля его (процесс) контролирует кто-то извне – зависимость «впрыскивют» модулю.
Используя метафору с проводами - модуль не должен думать о проводах, сборкой конструктора занимается кто-то другой, а не сами детали.
2 Количество зависимостей
Вполне очевидно, что чем меньше зависимостей, тем ниже степень связанности. Уменьшить их количество можно сужая обязанности каждого модуля, разделяя крупные модули на несколько мелких ( руководствуясь принципом High Cohesion ). С другой стороны, следует учитывать, что это палка о двух концах: чем больше стыков, тем больше кода описывающего связи, поэтому совсем не обязательно рубить приложение в винегрет.
Кроме того можно уменьшить область знаний каждого модуля (Закон Деметры, LoD), например разделив приложение на этажи или зоны и разрешив общение модулей только в пределах соседних зон.
3 Сила зависимостей
Интерфейс ограничивает знание одного модуля о другом.
Например: объекту класса А, умеющему обращаться с интерфейсом IB, можно подсунуть любую из имплементаций этого интерфейса, и он сможет ей управлять, не вникая в то, как именно называется или устроено то, что ему дали.
События или сигналы, это тоже менее жёсткая зависимость.
Отправитель ничего не знает о получателе, рассылка происходит по подписке.
Надеюсь, ничего важного не упустил.
Но если упустил, то буду рад комментариям.
Всего комментариев 20
Комментарии
10.01.2012 23:29 | |
Почему объектно-ориентированное программирование провалилось?
Цитата:
Самый гибкий подход это избавить модуль от необходимости заботится об этом вообще. Такой подход называется инверсия контроля (inversion of control, IoC) или Dependency Injection.
В общем, еще один астронавт архитектуры [x] |
|
Обновил(-а) artcraft 11.01.2012 в 00:02
|
10.01.2012 23:43 | |
Цитата:
Почему объектно-ориентированное программирование провалилось?
Цитата:
Это вы сами придумали или подсказал кто-то (ссылочку на пруф пожалели)?
Может со словосочетанием "самый гибкий" я и загнул немного, но буду рад обсудить. Цитата:
В общем, еще один астронавт архитектуры [x]
еще один всё понял [x] |
|
Обновил(-а) artcraft 10.01.2012 в 23:59
|
10.01.2012 23:55 | |
Статьи об ООП должны сами придерживаться этих принципов. Быть небольшими, описывать конкретные вещи и с примерами.
|
11.01.2012 00:01 | |
Вы пытаетесь замусорить мозги пересказами. Ну так делайте это технично!
|
11.01.2012 00:28 | |
Я оч уважаю чужие мнения. По вашему мнению
Цитата:
Да вот собственно, первое предложение http://ru.wikipedia.org/wiki/Инверсия_управления
Цитата:
Инверсия управления (Inversion of Control, IoC) — важный принцип объектно-ориентированного программирования, используемый для уменьшения связанности в компьютерных программах.
Вы не смогли воспользоваться другим источником? На некоторых уютных бложиках истово минусуют за вики. |
11.01.2012 03:00 | |
Цитата:
воспринимайте этот пост как оглавление будущих постов в этом блоге
|
11.01.2012 11:22 | |
Все здорово, но без примеров и рисунков вылетает из головы через минуту.
|
11.01.2012 19:25 | |
Цитата:
в чём разница между IoC и DI?
|
11.01.2012 20:03 | |
хорошая ссылка, и там как раз написано что DI это IoC, но IoC это принцип, а DI это паттерн, точнее один из паттернов реализующих принцип, так что называть их разными вещами не совсем правильно
|
|
Обновил(-а) artcraft 11.01.2012 в 20:09
|
11.01.2012 21:13 | |
Техника внедрения принципа и принцип построения системы - это одно и то же?
|
11.01.2012 21:41 | |
нет конечно, где я это утверждал?
DI это IoC, как, например cова это птица, но обратное утверждение не верно, IoC более широкое понятие я оспорил только утверждение что "сова и птица это разные вещи", они разные только с одной стороны |
|
Обновил(-а) artcraft 11.01.2012 в 21:44
|
11.01.2012 21:45 | |
Цитата:
DI это IoC
Скорее - это метод вколачивания гвоздя как реализация принципа - соединить 2 доски вместе. Но это детали. Да. |
|
Обновил(-а) Котяра 11.01.2012 в 21:47
|
11.01.2012 21:56 | |
Поменял формулировку в статье на однозначную
|
13.01.2012 14:20 | |
Цитата:
Почему объектно-ориентированное программирование провалилось?
|
14.01.2012 20:34 | |
Цитата:
Как мой тимлид. Он сказал - "Я не буду спорить! Я просто прав,... иначе твои действия, мы признаем как саботаж проекта..."
- "Просто поверь" - "Мое подсознание, подсказывает, что с таким подходом мы огребём" Или дешёвыми психологическими трюками: - "Это же удобно, почему ты не хочешь так сделать?" - "Копипастить тоже удобно, только почему-то приводит к проблемам" - "Давай сделаем X" - "Aга, давай еще запихаем X в Y" |
|
Обновил(-а) expl 14.01.2012 в 20:37
|
Последние записи от artcraft
- Что такое entity framework (12.09.2012)
- Подводные камни Dictionary (04.09.2012)
- Волшебное превращение Object --> Class (04.09.2012)
- Инверсия контроля (14.04.2012)
- Loose coupling (10.01.2012)