Почему веб-архитектура должна быть слабосвязанной?

Когда я смотрю на проекты ASP.NET MVC, я каждый раз вижу слабосвязанную архитектуру.

Для чего мне нужна слабая связь в веб-архитектуре (если я не делаю модульные тесты)?

Каковы преимущества и недостатки этого?

Какова основная причина разделения слоев / классов?

Что, если я, например, не хочу менять свой DAL? Я имею в виду, когда я должен полностью изменить свой DAL ?! Так что я мог связать свой DAL с пользовательским интерфейсом. Что в этом плохого?


person Rookian    schedule 19.05.2010    source источник


Ответы (13)


Это сэкономит вам много времени для любого нетривиально маленького проекта, где я определяю тривиально маленький как менее пары тысяч строк кода (в зависимости от языка).

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

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

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

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

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

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

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

person Davy8    schedule 28.06.2011

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

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

person Justin Niessner    schedule 19.05.2010
comment
И я бы добавил «проще в обслуживании». Если их не легче поддерживать в долгосрочной перспективе, вы делаете что-то не так. - person Dan Esparza; 19.05.2010
comment
То же. Слабая связь, тесная сплоченность - всегда лучший выбор. Одна из немногих полезных сведений, которые я извлек из своего класса SE. - person ubiquibacon; 19.05.2010
comment
Что делать, если мне не нужно разделять слои? Когда пора менять весь DAL? Меня не волнуют теоретические вещи, которые могут произойти. - person Rookian; 29.06.2011
comment
Вам нужно найти баланс. Вы можете все отделить, а зависимости внедрить все, но если вы не собираетесь их менять, зачем вам это делать? Группируя функциональные возможности вместе, вы улучшаете повторное использование вашего приложения. Возможно, вы никогда не захотите изменить DAL, но если вам нужно изменить способ его работы или добавить новую функцию, у вас есть 1 место для этого. - person Simon Halsey; 30.06.2011
comment
факт изменения только одного местоположения применяется только тогда, когда вы не вносите больших изменений, верно? - person Rookian; 03.07.2011

На бумаге есть много преимуществ слабой связи, но на практике сделать это сложно ИМХО. Вот некоторые преимущества:

  • Системы могут развиваться независимо с точки зрения жизненного цикла.

  • Системы могут быть написаны на разных языках и, в конечном итоге, работать на разных ОС.

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

Но вот некоторые недостатки:

  • Вначале это больше работы, и если вы не сделаете это хорошо, вы никогда не увидите пользы от этого.

  • Определение API / контрактов довольно сложно и требует очень опытных разработчиков. Вначале это легко сделать, но в долгосрочной перспективе это будет непросто.

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

  • Некоторые методы слабой связи основаны на обобщении определения интерфейсов с целью избежать прямой зависимости. Помните, что после определения и публикации интерфейс должен быть высечен в камне. Это не совсем то, что я называю слабой связью. Класс .NET, использующий JIT и такие методы, как перегрузка метода, может быть лучшим инструментом слабой связи. Итак, проблема с этими интерфейсами и фабриками повсюду в том, что это приведет к умножению типов, сборок, тестовых примеров и т. Д. И просто к большему количеству работы и сложности в будущем. Вместо того, чтобы упрощать вещи, вместо того, чтобы строить одну систему, вам придется построить множество. "N-уровневая система - это в N раз больше работы" :-)

  • Слабая связь каким-то образом обходит один из самых мощных инструментов, когда-либо созданных: компилятор (C # или другие). И в этом вся его цель, но у нее определенно есть некоторые недостатки, потому что всю основную работу, которую выполнял компилятор (проверка типов и т. Д.), Нужно будет выполнять где-то в другом месте (тесты), а это будет стоить.

  • Многие готовые инструменты, вероятно, больше не будут работать. Вы не сможете использовать такие вещи, как Visual Studio «Перейти к определению» или «Найти все ссылки».

person Simon Mourier    schedule 28.06.2011
comment
+1 за ... если вы не сделаете это хорошо, вы можете никогда не увидеть пользы от этого. - Вероятно, большая причина, по которой многие не понимают его преимуществ. - person JeroenEijkhof; 05.07.2011

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

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

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

person driis    schedule 19.05.2010

Я думаю, что «правильный» путь объяснялся в других ответах. Но напишу сейчас на собственном опыте.

Есть несколько вещей, которые вы должны учитывать при выборе архитектуры.

а. Клиент

У вас есть достаточно времени, чтобы сделать все «правильным» (отличная архитектура, тесты и т. Д.)? Иногда клиент хочет быстро увидеть результат. Мы можем пожаловаться на то, что времени мало, и продукт не будет соответствовать самым высоким стандартам, но, в конце концов, это наша проблема. В таких ситуациях мы объясняем клиенту, что он получит, и пишем известный всем нам спагетти-код.

Каковы требования клиентов (с точки зрения надежности, масштабируемости, расширяемости, скорости)? Я думаю, это не требует пояснений. Иногда клиент диктует «правильный» путь. Мы можем предложить клиенту «правильный» путь, но в конечном итоге все будет решать клиент (конечно, в зависимости от времени и денег).

Кто будет поддерживать систему после того, как вы ее разработаете? Я хотел бы поддержать красивый и несвязанный код. Поэтому, когда я пишу код, я стараюсь сделать его «правильным». Когда-нибудь я мог бы соединить представление и контроллер или соединить какой-нибудь сервис и быть доволен этим. Зная свой собственный код, его легко поддерживать.

б. Проект

Каков размер проекта? Некоторые проекты настолько малы, что не требуется сложной архитектуры.

Есть ли шанс на быстрое развитие программного обеспечения в будущем (больше функций)? Это одна из самых больших проблем. Но если программа растет, значит, она успешна. У вас, вероятно, будет больше ресурсов для работы. Реорганизовать код и сделать его «правильным» относительно легко.

Будут ли у проекта проблемы с масштабируемостью? Есть проекты, которые никогда не будут расти с точки зрения пользователей и данных. Я видел проекты, которые пытаются выглядеть серьезно, используя настройку базы данных Oracle RAC, когда простая встроенная база данных будет работать нормально!

Вы начали проект или перенимаете его у других разработчиков? Это комбинация вопросов о том, кто будет поддерживать программное обеспечение и будет ли оно расти. Вы можете получить спагетти-код от других разработчиков. Будет ли у вас время и ресурсы, чтобы сделать это «правильным»?

c. Команда разработчиков

Достаточно ли у команды опыта, чтобы правильно выполнить развязку? Когда я был менее опытен, я пытался написать «правильный» код. И я потерпел неудачу. Дело в том, чтобы действительно знать свою команду разработчиков, их навыки и знания. Не стоит недооценивать эту проблему. Работая с менее опытными разработчиками, я обычно жертвую архитектурой. Жертва, которая будет принесена, - это наиболее обоснованное предположение, которое у меня есть. Есть некоторые моменты в архитектуре, которыми вы можете пожертвовать, а есть некоторые, которыми вы не можете. Обычно одна или несколько жертв, которые вы принесли ранее, вернутся и укусят вас.

Есть ли у разработчиков опыт написания автоматических тестов? Недостаточно иметь автоматические тесты. Они должны быть полными (насколько это возможно) и выполнены правильно. Если ваши тесты слабые, то лучше вообще их не брать. Не стоит опираться на дырявую стену.

Заключение:

Я знаю, что все мы хотим быть профессионалами. И, как профессионалы, мы должны все учитывать. Мы не можем тратить время и энергию на то, чтобы делать что-то «правильным» образом. Иногда мы должны смотреть на другие факторы (реальность) и делать свой выбор. И самое главное - с этим жить.

person Bojan Milenkoski    schedule 05.07.2011

Преимущества:

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

Недостатки:

  • Возможно, несколько лишних строк кода
  • Некоторые дополнительные классы интерфейса
person Nicholas Murray    schedule 19.05.2010

Во-первых, вы должны писать модульные тесты;)

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

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

person dbyrne    schedule 19.05.2010

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

Здесь вы можете увидеть интересную небольшую статью: SOA - Loosely Coupled ... Что?

Вкратце говорится:

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

person Incognito    schedule 19.05.2010
comment
Но что, если мне не нужно менять компоненты во время выполнения? Я не могу понять вашу точку зрения о масштабируемости. - person Rookian; 19.05.2010
comment
Например, если вы используете подход SOA, вы можете разделить свои службы для работы на разных серверах. Даже если вам не нужно менять компоненты во время выполнения, вы получите преимущества от слабосвязанной архитектуры. Например, вы используете сервер MS SQL в качестве БД и используете ADO.NET в качестве поставщика данных для взаимодействия с ним. И как только вам нужно будет перейти на Oracle даже в любое другое хранилище данных (даже это могут быть файлы xml ...), вам нужно будет обновить все модули, имеющие дело с ним. Но если для этого у вас будет уровень обслуживания, вам нужно будет изменить только уровень обслуживания. - person Incognito; 19.05.2010
comment
Так что, как правило, вы можете иметь как правило - Измените все, что хотите, но не договор. - person Incognito; 19.05.2010

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

person duffymo    schedule 19.05.2010

Основная причина объединения и разделения классов заключается в расширяемости. Изменение одного не должно влиять на другое.

если вы создаете приложение, которое в настоящее время использует базу данных MYSql для хранения данных. Теперь у нас есть новое требование хранить данные в MSSQL в качестве его серверной системы. Какое решение у вас останется, если вы построите систему, более интегрированную с библиотеками MYSQL. Переписать все приложение под MSSQL. А как насчет этого? Мы создаем новый DAL на основе MSSQL и подключаем DAL к системе, не внося никаких изменений в систему (UI).

Приложение вызывает процедуру на основе интерфейсов, а интерфейсы свободны от реализации.

Попробуйте прочитать о Unity или MEF, эти темы дадут вам хорошее представление

person Amit Bagga    schedule 02.07.2011
comment
Что делать, если расширяемость не нужна? зачем вам заменять весь свой DAL? - person Rookian; 03.07.2011
comment
Если вам не нужна расширяемость, вы можете работать со своим традиционным подходом. Но в сегодняшней парадигме всегда нужно думать о расширяемости. Программное обеспечение постоянно развивается; требование делать изменения. и архитектура тоже. Хорошим примером может служить обработка платежей через продавца xxx, а завтра мы хотим переключиться на другого продавца. Процесс обработки платежа тесно интегрирован в систему, что потребует огромного объема работы для его упрощения. - person Amit Bagga; 03.07.2011
comment
В слабо связанной архитектуре это изменение будет легко реализовать, и это не повлияет на основное приложение, все, что изменится, - это DLL, и нам не придется перекомпилировать основной код пользовательского интерфейса. - person Amit Bagga; 03.07.2011
comment
@Rookian, расширяемость не всегда означает замену всего вашего DAL или любого уровня, но также и плавное добавление функциональности к существующему приложению или изменение только части приложения, не затрагивая другие части, которые к настоящему времени отлично работают. Кроме того, разделение позволяет многократно использовать код между проектами (поэтому похожие проекты будут создаваться быстрее). Может быть, если вы познакомитесь с такими архитектурами и почему они так устроены, вы ответите сами. Просто найдите время и почитайте по теме. - person Ivaylo Slavov; 05.07.2011
comment
Спасибо @lvaylo за то, что добавили дополнительную ценность этой теме. - person Amit Bagga; 05.07.2011

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

Итак, преимущества: -

1) Если вы используете сторонний элемент управления / код: всегда пишите «слой оболочки / адаптера», чтобы по какой-либо причине, если он не может использоваться, вы могли получить что-то еще и изменить уровень адаптера без нарушение кода репозитория вашего приложения.

2) Инкапсуляция определенных сложных функций на «уровне обслуживания», который может потребовать или не потребовать запросов к базе данных: это полезно, потому что, поскольку запрос и ответ остаются неизменными (они, безусловно, могут измениться со временем), вы всегда можете работать над производительностью этого конкретного кода, не изменяя вывод. Имея единичные кейсы, мы также можем измерить производительность кода.

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

4) Целенаправленное обеспечение качества: если у нас многоуровневая архитектура, это всегда помогает улучшить качество, если оно сфокусировано.

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

Недостатки: -

1) Настройка приложения с таким фреймворком займет дополнительное время. Так что «выход на рынок» будет отложен.

2) Если вы станете слишком энтузиастом технологий, это может закончиться чрезмерным убийством.

3) Дополнительная задержка транзакции: поскольку данные проходят через различные уровни, возникает дополнительная задержка, которая добавляется в каждую транзакцию.

По поводу смены DAL: -

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

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

Вот почему, изначально всегда лучше потратить время и сделать вывод, когда произойдет «самоуничтожение» приложения. Я имел в виду, что за жизнь Приложению, если на это ответят хорошо, остальное все встанет на свои места.

person Wali    schedule 05.07.2011

Разделение труда, которое является человеческим эквивалентом разделения интересов. Ваш гуру HTML должен уметь работать независимо от вашей богини SQL.

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

person Matt Sherman    schedule 20.05.2010

Ответ с точки зрения, о которой больше никто не говорил; временная развязка. Это можно сделать несколькими способами:

  • Архитектуры на основе очередей, в которых Интернет помещает сообщения в очередь и ожидает результатов
  • Избегайте блокирующих операций, в первую очередь за счет использования асинхронного шаблона или асинхронной монады, которая связывает продолжения с обратными вызовами операций, позволяя потокам работать в ожидании ввода-вывода. Пример: http://blogs.msdn.com/b/dsyme/archive/2007/10/11/introduction-f-asynchronous-workflows.aspx или http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style
  • Архитектуры на основе push (например, AMQP basic_consume)
  • Шаблоны вилочного соединения
  • ...

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

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

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

Для различных типов связывания типа компиляции (и других показателей) просмотрите http://www.ndepend.com/Metrics.aspx и прочтите об этом сами.

person Henrik    schedule 05.07.2011