Почему в проекте SOA так плохо работают CRUD?
Я только что закончил читать статью о MSDN от John Evdemon. Он использует интерфейсы CRUD и называет его анти-шаблоном.
Хотя я согласен с тем, что иметь что-то неактуальное, и Current и MoveNext - плохие идеи, я не согласен с тем, что CRUD, как и в Create Update Update и Delete, плох. Если у меня есть автосервис, и я хочу, чтобы клиенты могли делать основы, например, в "Создавать автомобиль", получать детали автомобиля, обновлять детали автомобилей или удалять автомобиль, то как они должны быть способны делать эти вещи? без операций CRUD.
Или что мне здесь не хватает?
Ответы
Ответ 1
Интерфейсы CRUD следует избегать в сценарии распределенной системы /SOA, поскольку они очень чаты. Но это не значит, что нужно. Когда у вас есть некоторые действия с клиентом, для которых требуется более одного вызова вашей услуги, вы знаете, что вам следует отказаться от подхода CRUD и создать новую сервисную операцию, которая будет связывать эти вызовы с одним вызовом. При проектировании распределенной системы вы должны всегда уменьшать количество вызовов до минимума, потому что сетевой вызов занимает очень много времени.
Edit:
Вы можете думать о интерфейсе CRUD как о доступе к данным, который отображается в службе. Иногда ты действительно этого хочешь. Но в SOA и распределенной системной архитектуре вы обычно раскрываете бизнес-функциональность, которая уже обертывает доступ к данным и предлагает гораздо более сложные операции (которые объединяют многие операции доступа к данным).
Пример:
CRUD x Интерфейс бизнес-логики. Предположим, что вы работаете с Invoices
. Каждый счет-фактура состоит из InvoiceHeader
и одного или нескольких InvoiceLine
. Если вы используете интерфейс CRUD для счета-фактуры, вы сначала вызываете операцию CreateInvoiceHeader
для создания InvoiceHeader
, а затем несколько операций AddInvoiceLine
, чтобы добавить все InvoiceLines
- это подход низкого уровня CRUD. Но если вы реализуете бизнес-логику со стороны службы, вы будете называть одиночный CreateInvoice
и передавать в объект службу сложный граф объектов (заголовок со всеми строками) для создания и добавления того, что необходимо. Метод Create
также может выполнять другие бизнес-операции, такие как запуск некоторого рабочего процесса и т.д. Это обычный SOA и распределенный системный подход.
Ответ 2
RESTfull веб-сервисы, которые в последнее время набирают популярность, доказывают, что пост г-на Джона Эвдемона не соответствует.
Ответ 3
Я думаю, что он специально разработал худший возможный интерфейс здесь, и это не действительно интерфейс CRUD.
<WebMethod()> _
Public Function MoveNext() As Boolean
End Function
<WebMethod()> _
Public Function Current() As Object
End Function
Эти два метода, очевидно, не являются апатридами, но также не нужны для истинного интерфейса CRUD. Я думаю, что это очень плохо написанный пример, и он не связан с операциями CRUD.
Update:
Нашел аналогичный вопрос с очень хорошим ответом:)
Ответ 4
Принятый ответ неверен. И, несмотря на то, что Джон использует CRUD в качестве примера анти-шаблона с использованием CRUD, это не плохо для SOA. Здесь проблема с SOA, как описывает Джон: она поощряет повышенную сложность на уровне обслуживания, что в конечном итоге приводит к меньшей поддержке нескольких случаев использования. Одной из основных причин, по которым мы создаем API, является предоставление доступа к нескольким приложениям, здесь первичная рентабельность инвестиций заключается в создании API-интерфейсов.
Например, скажем, у нас есть API-интерфейс блога. Скажем, мы даем пользователям возможность писать сообщения, добавлять изображения и размещать комментарии на одном экране нашего внешнего приложения. В Джоне видение SOA он, вероятно, рекомендовал бы, чтобы мы построили наш API, чтобы использовать один вызов для выполнения всех этих вещей, чтобы он был менее болтливым и бла-бла-бла... так:
{
"post_title": "New Post",
"post_content": "Some Stuff....",
"comments": [{
"comment": "This is right on!",
"userId": 101
}, {
"comment": "I agree.",
"userId": 105
}],
"images": [{
"imgURL": "http://some.img.com/1"
}, {
"imgURL": "http://some.img.com/2"
}]
}
Теперь есть, очевидно, три разных объекта данных, которые нужно отдельно хранить здесь: сообщение, комментарии и изображения. С точки зрения хранилища данных сообщение переходит в таблицу POSTS к комментариям в таблицу КОММЕНТАРИЙ и изображения в таблицу ИЗОБРАЖЕНИЙ. Поэтому, если мы построим наш сервис, следуя за арендаторами SOA, как описывает их Джон, мы делаем наш один вызов с нашим объектом, и он выполняет службы, которые пытаются создать сообщение, которое, например, цели, прекрасно работает, тогда он пытается создать комментарии, которые работают нормально, но когда мы добираемся до изображений, служба понимает, что один из URL-адресов изображений ошибочен, терпит неудачу. Итак, наш сервис возвращает сбой? Несмотря на то, что еще 3 части теперь успешно хранятся в нашем хранилище данных? Вернемся ли мы назад и отменим все части, которые успешно выполняются? Что делать, если хранилище данных уже совершило изменения, и мы не можем отбросить его назад?
Объедините это с тем, что, если бы мы сделали его "более болтливым" и представили его индивидуально, мы могли бы повторно использовать эти службы в других приложениях, не переписывая какую-либо часть сервиса.
Плохая часть консолидированных услуг заключается в том, что вы продаетесь по идее, что сервис никогда не должен терпеть неудачу... что смешно. Всегда будет краевой случай, когда что-то потерпит неудачу, и, объединив все в одну услугу, вы увеличили свою сложность и фактически увеличили свою способность к сбою.
Я бы сравнил эту версию SOA с недостатками, которые мы уже реализовали при построении объектов God в объектно-ориентированном программировании. https://en.wikipedia.org/wiki/God_object
Мы знаем лучше, чем это, поэтому зачем мы его переигрываем? Сводные или богослужения - плохая идея, как объекты Бога. Я говорю, создайте свои услуги, чтобы сделать одно и сделать это хорошо для как можно большего числа случаев использования, и ваш сервис будет хорошим.