Pull to refresh

Взаимодействие звеньев и их изоляция. Часть 1

Designing and refactoring *
Translation
Original author: Chad Z. Hower aka Kudzu
Логические звенья в n-звенных системах должны проектироваться так, чтобы они взаимодействовали и подвергались влиянию только соседних звеньев. Данное ограничение зачастую нарушается, что негативно влияет на систему. В этой статье я расскажу почему так обычно случается, о последствиях, и почему следует уделять большое внимание изоляции слоев.

Статья посвящена основам и является детальным их описанием. Следующие статьи с подробными примерами будут основываться на ней. Данная статья построена на принципах, которые мы обсуждали в «Где наша бизнес-логика, сынок?» («Dude, where's my business logic?»).

Физические звенья


Рассмотрим как располагаются относительно друг другу физические звенья:



В этом примере представлена 3-х звенная система. Все звенья могут взаимодействовать только с соседними слоями.



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

Звенья слоев


Термины звено (tier) и слой (layer) часто используются как взаимозаменяемые. Когда я использую термин «звено», я подразумеваю физическое звено. Когда я использую «слой», я подразумеваю исключительно логический слой. Слои существуют в пределах звена, и, соответственно, звенья состоят из слоев.



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

Слой бизнес-логики в звене хранения данных




Слой бизнес-логики в звене клиента




Логический Лимб


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



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



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


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



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

Я продемонстрировал только верхний уровень. Однако, каждый слой имеет свои дополнительные подслои.



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



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



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

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


Шаблоны проектирования


Шаблон проектирования от слоя хранения данных



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

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



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

Шаблон проектирования от слоя представления




При этом подходе, слой хранения данных проектируется, основываясь на слое представления. Реализация слоя бизнес-логики обычно состоит из простых SQL-запросов и практически не производит трансформации или изоляции. Базы данных плохо спроектированы и имеют проблемы с производительностью, т.к. они изначально были сделаны для удобного предоставления данных слою представления, без учета нормализации и прочих требований типичных для баз данных.

Шаблон изолированного проектирования




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

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

Проектирование от слоя хранения данных Проектирование от слоя представления Изолированное проектирование
База данных
  • Хорошо спроектирована
  • Присутствуют некоторые нежелательные компромиссы
  • Тяжело вносить изменения, т.к. к ней жестко привязан слой представления
  • Плохо спроектирована
  • Денормализована
  • Трудна в использовании прочими системами
  • Тяжело вносить изменения, т.к. к ней жестко привязан слой представления
  • Может быть хорошо спроектирована
  • Используется исключительно для хранения данных, и лишена влияния слоя представления
Бизнес-требования
  • Зачастую не соответствует бизнес-требованиям
  • Зачастую соответствует бизнес-требованиям
  • Cоответствует бизнес-требованиям
Масштабируемость
  • В целом, масштабируется, но зачастую требует серьёзных изменений в пользовательском интерфейсе, для отражения изменений в структуре данных, или дублирования данных
  • Имеет врожденную проблему масштабирования.
  • Дублирующийся функционал является нормой
  • Просто масштабировать




Хочу извиниться перед общественностью за то, что разбил статью на две части. Но в последнее время большие тексты перестали приниматься Хабром. Если кто-то подскажет как с этой напастью справиться: буду благодарен.
продолжение
Tags:
Hubs:
Total votes 46: ↑41 and ↓5 +36
Views 4K
Comments Comments 10