7/6/2011 4:39:32 PM

Ниже мои заметки с курса, кусками (середина уже):

SOA предполагает “разделение” системы на “сервисы”.

Сервис определён как “the technical authority for a specific business capability”.
Это значит, что предписывается строить приложение не с использованием bottom-up подхода, а с использованием top-down подхода.

Bottom-up подход:
Делаем систему для продажи товаров.

Значит у нас есть объекты:
Customer of LoginName * FirstName * LastName * Status * 
Address of AddressType * Country * City * Street
Product of Title * Description * Price
и т.д, разные другие логичные свойства и сущности

Делаем таблички для этих сущностей, это у нас слой БД. Берём EF4, это у нас модель. Делаем репозитории с операциями CRUD и всякими другими интересными, это у нас слой бизнес-логики. Делаем UI для всего этого дела.

Top-down подход:
Делаем систему для продажи товаров, но перестаём впихивать бизнес в термины базы данных.

Определяем business capabilities, то есть, изучаем бизнес и смотим, что и где происходит, какие данные изменяются совместно, какие требования изменяются совместно.
Приходим к мысли, что наш объект Customer из примера выше – сущность странная и не имеющая смысла ни в реальном мире, ни в мире бизнес-логики приложения. Остаётся загадкой, почему мы считаем её логичной.
Например, у меня, как у кастомера, есть имя и фамилия. Но у меня нет статуса. Этот “статус” существует для меня где-то отдельно от меня, причём в разных местах у меня могут быть разные статусы и т.д.

С точки же зрения бизнес-логики такая компоновка объекта Customer смысла тоже, скорее всего, не имеет.
Потому, что очень маловероятно, что бизнес-логике, осуществляющей работу c кастомером, когда-нибудь потребуется его логин или пароль. Очень маловероятно, что потребуется некий “статус” который, в свою очередь, будет требоваться там, где будет осуществляться работа с ценами и продажами, но там вряд ли кого-то будут интересовать не только логин и пароль кастомера, но и его имя, и его адреса.
Соответственно, с точки зрения биллинга кастомера, нас не интересует ничего, кроме кредитной карты и, может быть, биллинг адреса. Нас не интересует адрес доставки в этом случае так же, как бизнес-логике, отвечающей за доставку, не нужна информация о кредитной карте и адресе для биллинга.
Или, вот, скажем, продукт и его цена. Там, где мы имеем дело с описанием продукта, его спецификациями и т.д, его цена вряд ли имеет смысл. Более того, у продукта нет как таковой цены, ибо цена обычно есть функция времени, если бизнес-требования не диктуют фиксированых цен навсегда, чего они обычно не делают. Таким образом, цена продукта это всегда цена когда?.

Ну и так далее.
Получается, что определив определённые границы business capabilities для приложения мы получаем определённый набор сервисов.
В каждом из этих сервисов понятия Customer, Product и т.д. отличаются. Скажем, в сервисе аутентификации пользователь – это его логин и пароль, в сервисе продаж – статус, в сервисе биллинга – кредитная карта и адрес биллинга и т.д. и т.п.

Чётко определив границы business capabilities можно двигаться дальше и сказать, что каждый сервис технически – это solution в вижл студии, это отдельная ветка кода. Он никак не связан с другими сервисами. У него есть своя бизнес-логика, своя схема БД и всё, остальное, что полагается, если это нужно.

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

Между собой сервисы могут обмениваться событиями, RPC между сервисами недопустимы.
Причём события одного сервиса имеют смысл в контексте самого сервиса и не более. То есть, сервис, занимающийся биллингом клиента, не может послать событие “а теперь заказ нужно отправить почтой”. Он только может послать событие “Клиент был забиллен”.
Сервис, занимающийся доставкой, подписывается на события, и это он и только он решает, когда можно оправлять товар, а когда ещё нет. Например, может быть нужно дождаться какого-то другого события кроме “клиент забиллен”, скажем, “заказ подтверждён”, и отправлять только тогда, когда оба эти события для заказа имели место произойти.

Тут вырисовываются интересные вещи.
Например, раз у сервисов разные базы данных, то мы не можем гарантировать referential integrity.
Но вопрос стоит в том: а нужно ли нам это? Если, скажем, мы получили событие “кастомер 5 положил в карту товар такой-то”, а где-то в другой базе пока ещё нет никакой информации о кастомере 5 (проблема с сетью, сервис “лежал”, обработка длится дольше и т.д), то является ли это проблемой?
С точки зрения IT-мозга – да.
С точки зрения бизнеса… Скорее всего – нет. Люди, наблюдающие за статистикой продаж, сильно вряд ли интересуются конкретными именами покупателей. Поэтому мы, скорее всего, вполне можем позволить себе получить событие о том, что товар положен в карту до того, как мы получили имя клиента.
Потому, что это разные business capabilities.

Поэтому мы можем иметь независимые друг от друга сервисы, которые могут быть установлены на одну и ту же, либо на разные физические машины, которые могут иметь совершенно разные структуры баз данных (или, что там говорить, вообще совершенно разные СУБД, где-то, быть может, будет более уместно использовать NoSQL и хранить там документы, где-то файловую систему и хранить там тонны сгенерированных по документам тайлов и т.д.)
Мы получаем возможность вертикального партицирования, а с ним – много других интересных возможностей, например, возможность перераспределить ресурсы и сделать какой-то аспект системы более приоритетным, нежели другой в терминах используемых ресурсов (например, размещение заказа гораздо более приоритетная операция, чем, скажем, отображение terms and conditions).

Comments (1) -

7/7/2011 8:12:02 AM

Евгений

"Таким образом, цена продукта это всегда цена когда?"
Цена всегда велечина с историей. ;)
По соа, вопрос лишь в уровне, и давно уже имеет место быть на уровнях предприятия и выше, ну а как иначе то....

Евгений Russia

Comments are closed

Powered by BlogEngine.NET 2.5.0.6

About the author

Alexey Raga Alexey Raga
.NET software developer.

E-mail me Send mail

Twitter

Widget Twitter not found.

Root element is missing.X


Recent posts

Archive

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

Sign in