Pull to refresh

Comments 59

У многих разработчиков важность этапа проектирования недооценена. Шире надо мыслить!
По моему мнению, на проектирование нужно закладывать в 2-3 больше времени, чем на реализацию.

Проектирование — это творчество, а реализация — это тупо ремесло.
В теории, теория и практика — одно и тоже, но на практике — это совершенно разные вещи. (с) Эйнштейн.
Прошу прощения за занудство, но автор этого высказывания — не Эйнштейн, а Jan L. A. van de Snepscheut.
Оригинал: In theory, there is no difference between theory and practice. But, in practice, there is.

Все таки позанудствую — YII и CI — это скорее примеры сильно-связанных архитектур.
Абсолютно с вами согласен
Абсолютно верно. Если приводить примеры слабо-связанных архитектур из мира PHP, то скорее следует упомянуть Zend и Symfony.
UFO just landed and posted this here
Я бы даже еще уточнил, symfony2, на мой взгляд, единственный широко используемый php фреймворк, который можно безболезненно раздербанить на куски и использовать отдельно даже такие базовые компоненты как httpKernel и т.д. Правда zend2 я не смотрел…
Или свой фреймворк на базе компонент создать, написав один компонет. Сам фреймворк — компонента, такая же как остальные.
Как-то очень упрощено всё. А ваше абстрагирование так и чешется язык назвать декомпозицией. Абстрагирование (техническое) для меня процесс следующий за декомпозицией. Когда отдельные компоненты мы не просто выделяем, а выделяем через интерфейсы/публичные контракты, абстрагируясь от реализации, имея возможность её менять ничего больше не трогая.

И к последней схеме претензии есть — бизнес-логика почему-то с предметной областью связана через UI, а с сущностями не связана. Это как? Как по мне, так бизнес-логика непосредственно оперирует сущностями, а в ООП зачастую методами объектов сущностей и ограничена. И с UI взаимодействует поскольку постольку. Проще говоря, сущности+бизнес-логика=модель, UI=вид/представление, а, видимо, функциональная логика=контролер, если брать MVC.
Статья абсолютно не понравилась. Смесь общих, всем понятных фраз с какимито спорными высказаваниями, как быдто филологу попросили написать реферат об архитектуре.
Ключевым звеном слабосвязной архитектуры является выделение центрального компонента
— это вообще в некакие рамки не вкладываеться…

PS: с другой стороны прекрасная статья, вызавающая кучу неготивних имоцей и желания похоливарить ;)
Может быть, под центральным компонентом подразумевается Composition Root? Только зависимости на диаграмме неправильно нарисованы. Это Composition Root должен знать обо всех классах приложения, а сами классы ничего не знают о Composition Root.
Composition root нужен доя inversion of control, а не для слабо связанных архитектур.
Не представляю себе слабую связанность без инверсии зависимостей.
Сейчас никто не представляет. Но по факту это не обязательные вещи (а понятие «слабой связанности» — относительно, а не абсолютно).
Можете раскрыть тему?
Про относительность понятия слабой связанности.
Эмм.

Вы считаете, что «слабая связанность» — это флаг (либо слабая, либо сильная), а не относительная характеристика (слабее-сильнее)?
Одна захардкоженная зависимость слабее чем 10, а 10 слабее чем 20 :) Или, как вариант, 10% захардкоженных зависимостей слабее чем 50%, а 50% слабее чем 100% :)

А, теперь понятно. Вроде средней температуры по больнице… Например, наш проект слабо связан на 90%. Планируем ослабить его до 146% в этом году.
:) Нет, что-то вроде «господа, вам не кажется, что наш проект слишком сильно связан? Давайте ка на 50% уменьшим число связей»
«Господа, наш проект более-менее связан. Давайте сделаем его ещё менее связанным!»
Интересно, так будет лучше?
Кстати, идеалом тогда станет полное отсутствие связей!
Полное отсуствие связей это пул сообщений.
Нет, пул сообщений — это приравнивание числа связей к числу компонент.
Полное отсутствие связей — это неиспользуемый код )
McConnell, Code Complete, 2nd edition, глава Keep Coupling Loose (страницы 100-102), выделение мое:

A routine like sin() is loosely coupled because everything it needs to know is passed in to it with one value representing an angle in degrees. A routine such as InitVars( var 1, var2, var3, ..., varN ) is more tightly coupled because, with all the variables it must pass, the calling module practically knows what is happening inside InitVars(). Two classes that depend on each other’s use of the same global data are even more tightly coupled.
[...]
A routine that takes one parameter is more loosely coupled to modules that call it than a routine that takes six parameters. A class with four welldefined public methods is more loosely coupled to modules that use it than a class that exposes 37 public methods.
[...]
In short, the more easily other modules can call a module, the more loosely coupled it is…


Видите сравнительные степени («сильнее связано», «еще более сильно связано», «слабее связано»)?
Вижу, но здесь немного о другом речь. Я имел в виду физические ссылки на конкретные классы/модули. Они либо есть, либо их нет.
Но связность (coupling) ими не ограничивается.

(да и в этом случае степень связности все равно может быть различной)
Помимо структурной связанности есть семантическая связанность.
Статья хороша тем, что наглядно показывает разбиение системы на модули в общих чертах. Однако самое сложное, на мой взгляд, заключается во взаимодействии этих модулей, в том, что на картинках обозначено стрелками. Модули относительно легко проецируются в формат реального мира. Взаимодействие же требует более глубоких раздумий.
В слабосвязаной архитектуре не всегда есть центральный компонент. Я бы даже сказал такого нужно избегать. В каждом слое может быть несколько ключевых сервисов, каждый из которых выполняет только свои роли.
Спасибо за статью!
Хотя, статью можно было бы и не читать.
Достаточно былы бы картинки посмотреть, кроме последней. ;)
Каждую программу имеет смысл писать с учетом того, что некто будет сопровождать ее… Аксиома, не правда-ли?

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

Остальные пункты доставляют не меньше.

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

Такие красивые и понятные диаграммы типа вашей «ясной структуры» получаются только у двух типов программистов — у преподавателей-теоретиков и у впаривающих свои книжки консультантов. В реальности обычно всё немного не так радужно.

В-общем, удачи автору:)
Если я правильно понял, до здравствует Inversion of Control
Правильно, до здравствует :-)
Всегда присутствует сооблазн сесть и написать решение одним махом, из головы

У вас просто слишком простые задачи.
для любой даже супер гениальной головы есть сложные и непосильные задачи.
Жаль, что не каждому посчастливится их решать.
А теперь попробуйте удержать 22 сущности из «Ясной структуры»
Лично я себе представляю Big Picture хорошей архитектуры приложения как множество маленьких, слабо связанных абстракций и классов, из которых, как дом из кирпичей, мы собираем приложение. Т.е. делаем композицию классов в рантайме, в одном месте, например, с помощью IoC контейнера.
Гораздо сложнее представить, как эта композиция поведет себя в рантайме. Зачастую не совсем так, как задумано.
Это точно. Для крупных проектов просто необходима визуализация графа зависимостей, иначе никто не разберется как оно все работает)
Интеграционные тесты не?
Иногда код написан таким образом, что число веток растет по экспоненте.
В этом случае тесты не помогут — такое число веток ни один тест не покроет, либо тест окажется сравним по сложности с самим кодом.
В этих случаях, как правило, необходимо пересматривать код на предмет упрощения логики и разбиения на зап. части, которые можно будет тестировать независимо.
Да и вообще, если писать код, ориентируясь на его тестирование, он получается много проще… и писать его на порядок сложнее.
Число веток чего? Композиции зависимостей? Смешно.

Для того, чтобы разбивать на части, эта самая композиция и нужна, так что вы просто не отследили, в какую именно ветку отвечаете.
Пример — компонентная архитектура, со связями, основанными на событиях.
Код компонентов относительно (системы) не сложный, однако при наличии множества получателей или генераторов одинаковых событий структура runtime-связей будет далеко не тривиальной.
Как правило, интеграционные тесты в этих случаях покрывают только наиболее частые и значимые ветки.
Хм. Интеграционные тесты для такой системы должны, по идее, тестировать только то, что компонент генерирует событие определенного типа с определенными параметрами в ответ на событие другого определенного типа с другими определенными параметрами. То есть создаем фэйковый (стаб) генератор событий, фэйкового (мок) слушателя, регистрируем их в системе, вызываем у стаба метод генерации события с данными для тестируемой ветки, и проверяем, что мок получил ожидаемое событие с ожидаемыми данными. Всё, проверили, что этот компонент для данной ветки интегрирован в систему правильно, то есть правильно зарегистрирован, правильно принимает события и правильно обрабатывает их. И так для каждой ветки.

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

А уровень проверки рантайм-связей между компонентами — это уже уровень функциональных/приемочных тестов, которые пишутся на основе сценариев использования.

Согласен, перепутал терминологию.
Я имел в виду покрытие сценариев функционально/приемочными тестами.
А эти тесты, если есть хоть какие-то, то, по-моему, просто обязаны покрывать всю функциональность, описанную в ТЗ (явном или нет — не суть).
Центральный компонент в слабосвязной архитектуре несколько режет слух и намекает на антипаттерн «God Object». Хороший пример: GIT
Насколько мне известно, абстрагирование — это в первую очередь рассмотрение объекта, отбрасывая несущественные для выполнения задачи детали, а разделение программы на части является лишь побочным следствием абстрагирования. Мне кажется, что вместо абстрагирования стоило сослаться на «сильное зацепление» (про которое, как раз, часто и рассказывают в паре со «слабой связанностью»).

Про центральный компонент рассказано очень смутно. Это можно понять как то, что автор рекомендует создать один центральный компонент, который надо перегружать обязанностями (создавать «божественные» объекты). И лишь из схемы «Ясная структура» можно догадаться, что автор всё таки рассуждал о распределённой системе и «центральным компонентом» называл не более, чем одно из звеньев распределённой системы.

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

> Тут есть еще одна сильная сторона — именно центральному компоненту имеет смысл посвящать большое количество внимания, и таким образом вероятно экономится время на документирование и комментирование остальных.

Не понятно, какого рода внимание надо посвящать центральному компоненту и каким образом это может сократить объём документирования? Если разбить «лапшу» на отдельные компоненты и предположить, что под документированием здесь подразумевается документирование публичного API, то всё равно придётся документировать те из второстепенных компонентов, которые центральный компонент возвращает в виде результата публичного API.

P.S.: плюс, правильнее, неверное, называть «связанная», а не «связная», т.к. я часто встречал, что под «связностью» подразумевают перевод английского термина «cohesion», а не «coupling».
Подскажите пожалуйста, а в какой программе делали схемы? Извиняюсь, что не по теме.
Impress, есть в Open Office и в Libre Office.
Sign up to leave a comment.

Articles