WCF / SOA - Навіщо мені створювати об'єкти параметрів для простих запитів


12

Наша компанія починає досить велику ініціативу SOA. Ми робимо багато чого правильно: є хороша комунікація; гроші за інструменти, де це доречно; і ми використали хороший досвід, який допоможе нам у переході.

Ми намагаємось розробити стандарти, які ми можемо дотримуватись як група, і один із запропонованих стандартів мене дуже непокоїть:

Ми стандартизували схему, де кожна операція приймає об’єкт запиту та повертає об’єкт відповіді.

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

Більшість послуг, які я надаватиму, - це просте організаційне пошуку метаданих. Наприклад, знайдіть політику безпеки для конкретного користувача. Для цього потрібен ідентифікатор користувача та більше нічого. Стандарт каже мені, що я повинен обернути цей запит в об'єкт і обернути повернуту політику в об'єкт відповіді.

Моє занепокоєння посилюється поглядом на WSDL, який формується з наших контрактів. WCF автоматично генерує повідомлення про запит і відповідь і обгортає навіть об’єкт запиту / відповіді.

Я повністю розумію, що якщо ви робите складний запит, тоді складний вхідний об'єкт є гарантованим. Це ви б робили, навіть якщо служби не залучалися.

Моє запитання, чому я повинен автоматично завершувати запити та відповіді, коли:

  • Це робить прості сервіси менш виразними
  • Ви все одно зробите це для складної послуги
  • WCF все одно створює запит / відповідь

Я знайшов такі аргументи на користь такого підходу:

Він підтримує версію, дозволяючи необов’язкові параметри вставляти в об’єкт запиту.

Ще в той день я зробив неабияку частину COM, і вважав би це майже анти-схемою для версій. Для деяких речей, я думаю, це допомогло б, але я думаю, що там, де це допоможе, у вас все одно є об'єкт параметрів.

Це дозволяє виділити загальні дані та поведінку до базового класу

Цей несе з собою певну вагу.

Це відволікає людей від поведінки у стилі RPC та до поведінки повідомлень

Я читав це на сайті Microsoft і чув це від нашого гуру, але все ще не маю чіткого уявлення про те, що вони означають або чому це цінно. Хіба що інтерфейси природного вигляду змушують людей забувати, що вони дзвонять на віддалений сервіс?

Я дивлюся на рефакторинг підписів, можливо, 300 методів, тож це нетривіальна біль. Я величезний шанувальник послідовності в реалізації, тому я готовий взяти на себе біль, це просто допоможе дізнатися, що в кінці кінців все це буде вартим.

Відповіді:


3

Я думаю, що версії - це, мабуть, найкращий аргумент. Коли у вас є такий контракт на експлуатацію, як

int GetPersons(int countryId);

що ви хочете покращити, наприклад, іншим фільтром пізніше

int GetPersons(int countryId, int age);

Вам доведеться написати новий контракт на експлуатацію та нову назву, оскільки він повинен бути унікальним. Або ви збережете ім'я та опублікуєте нову версію своєї служби2, коли стара версія v1 все ще існує для зворотної сумісності.

Якщо ви загортаєте параметр в об'єкт, ви завжди можете його розширити за замовчуванням / необов'язковими параметрами, і всі ваші існуючі клієнти не будуть впливати при повторному використанні того ж контракту на експлуатацію.

Однак я також закликаю назвати ваші об'єкти належним чином. Навіть якщо він просто загортає цілий текст, якщо ви починаєте з IntMessageчимось подібним, ви не робите собі прихильності, розширюючи його. Ви повинні назвати його, наприклад, PersonFilterз самого початку, а це означає, що ви повинні трохи подумати над тим, що цей виклик служби повинен очікувати як параметр семантично, а отже, що він повинен робити. Можливо (і це дуже невиразно), що допоможе розвивати правильні сервіси та підтримувати API пристойних розмірів.

Це дозволяє виділити загальні дані та поведінку до базового класу

З цим варто бути обережним. Договори про спадкування та передачу даних не так добре поєднуються. Це працює, але вам доведеться вказати всі відомі підтипи договору, які можуть перейти через провід, інакше серіалізатор договору даних не вдається скаржитися на невідомі типи.

Але те, що ви могли зробити (але все-таки, мабуть, не слід, я все ще не визначуся з цим) - повторно використовувати ті самі повідомлення серед різних служб. Якщо ви кладете договори даних в окремий dll, ви можете поділитися цим між клієнтом і службою, і вам не потрібно конвертувати між типами, коли ви телефонуєте різним службам, які очікують в основному одне і те ж повідомлення. Наприклад, ви створюєте PersonFilter і подаєте його в одну службу, щоб отримати список фільтрів осіб, а потім до іншої служби та мати ті самі об’єкти на клієнті. Я не можу знайти для цього хорошого прикладу реального світу, і небезпека завжди полягає в тому, що розширення договорів даних не є загальним для всіх служб, які використовують цей контракт.

Загалом, окрім версій, я теж не можу знайти причину вбивці для цього.


Я думаю, що причина, чому я приймаю
Енді Девіс

(вибачте, інтерфейс коментарів викликає у мене горе) Дякую за відповідь. Я думаю, що причина, чому я приймаю аргумент версії з таким зерном солі, полягає в тому, що якщо ви додали новий аргумент, ви, ймовірно, змінили семантику. Якщо (як у вашому прикладі) ви щойно додали вік, то семантика, ймовірно, була для пошуку, і у вас там був "об’єкт пошуку".
Енді Девіс

Тепер розглянемо приклад моєї політики безпеки. Можливо, ми вирішили, що для того, щоб правильно поставити політику безпеки, нам потрібно знати не тільки користувача, але й об'єкт, над яким вони працюють. Це набагато більше, ніж додавання аргументу, ми змінили семантику виклику. Припускаючи, що ми якимось чином можемо надати цю інформацію для абонента попередньої версії, я думаю, що має більше сенсу версію договору на обслуговування. Тоді реалізація для старої версії може бути ізольованою, і ви не закінчите змішувати стару семантику з новою.
Енді Девіс

0

Примітки Мартіна Фаулера щодо об'єкта передачі даних тут, на мою думку, доречні.

Коли ви працюєте з віддаленим інтерфейсом, таким як віддалений фасад (388), кожен дзвінок на нього коштує дорого. В результаті вам потрібно зменшити кількість дзвінків, а це означає, що вам потрібно передавати більше даних з кожним викликом. Один із способів зробити це - використовувати безліч параметрів. Однак це часто незручно програмувати - дійсно, з мовами, такими як Java, які повертають лише одне значення, часто неможливо.

Рішення полягає в створенні об'єкта передачі даних, який може вмістити всі дані для виклику. Щоб перейти через з'єднання, це потрібно серіалізувати. Зазвичай асемблер використовується на стороні сервера для передачі даних між DTO та будь-якими об’єктами домену.

Те саме може стосуватися запитів. Що стосується RPC, і чому він поганий:

Хіба що інтерфейси природного вигляду змушують людей забувати, що вони дзвонять на віддалений сервіс?

Я думаю, що це правда, але не головна причина. Ще одна причина уникнення RPC полягає в тому, що він може заохочувати тісно пов'язані клієнти та послуги.


Дякую за внесок, але я не вважаю, що обговорення DTO є таким важливим. Це однакова кількість дзвінків, і якщо ви подивитеся на WSDL, все автоматично упаковується в об’єкт запиту та відкликання. Конвенція стосується видимої семантики, тобто люди повинні сприймати це як запит і відповідь на відміну від виклику віддаленого методу.
Енді Девіс

Чи хотіли б ви детальніше розробити RPC, що заохочують тісно пов'язані клієнти та послуги? Я не бачу, що це взагалі впливає на службу. Для клієнта я насправді не бачу, як щось насправді змінюється. У будь-якому випадку у мене є клієнт, який містить проксі-сервер, який описує ряд операцій, які надає послуга. Хто реально реалізує іншу сторону послуги, це ні в якому разі не клієнт.
Енді Девіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.