Чи повинен список параметрів методу містити об'єкти або ідентифікатори об'єктів?


10

Наші команди ведуть таку дискусію:

Скажімо, у нас є наступні два методи:

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

Що надсилаються по дроті - це лише ідентифікатори.

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

інша сторона каже, що другий метод є правильним, оскільки він більш гнучкий.

Ми знайомі з ідеєю об'єктних параметрів, інша сторона також вважає, що параметр об'єкта повинен мати об'єкти як властивості.

Який правильний підхід?

Можливо, є третій ще кращий підхід?


Що? ...........
Джеймс

1
Контекст? Веб-сервіс? WCF?
CodesInChaos

1
@James - вибачте, я швидко написав це запитання, чи можете ви сказати мені те, що не зрозуміло, щоб я міг його відредагувати?
Мітір

@CodesInChaos - це методи BL, фактично
Мітір

Відповіді:


10

Відповідь залежить від контексту.

Якщо очікується, що клієнт має всі ці об'єкти вже доступні , я б використовував параметри об'єкта. В іншому випадку їх код буде виглядати складніше, ніж потрібно. (Наприклад, у них будуть дзвінки club.getId(), наприклад,.)

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

Варіант полягає в наданні обох методів , щоб клієнт міг вибрати, який саме використовувати (враховуючи, що це не захаращує ваш API)

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

Нарешті, ваші підписи методу не повинні диктуватись специфікою того, що робить метод (у вашому випадку, що саме йде за межі). API повинен абстрактно мати сенс, тому, якщо впровадження зміниться, вас не накрутять.


3
+1 Я лише додам ще один момент: для методів, віддалених під назвою ("за проводом"?), Передача об'єктів може спричинити за собою глибоку серіалізацію великого дерева об'єктів. Ідентифікатори - це чудова заміна об’єктів, коли вас турбує розмір корисної навантаження віддаленого виклику.
Росс Паттерсон

1
У цьому випадку схоже на те, що ви поєднані з набором абстракцій, тому передача Id не придбає вам більшої гнучкості і, ймовірно, збільшить ймовірність зміни параметрів. Питання полягає в тому, наскільки щільно знаходиться код у методі в поєднанні з абстракціями, які я передаю? Наприклад, такий метод, як "validateCreditCard (string string, string cvi)", ймовірно, повинен залишатися з примітивами, щоб не бути щільно поєднаним з якимось об'єктом CreditCard.
ipaul

Я б зустрічався посередині і використовував інтерфейс у списку параметрів. Тоді ваш клуб може бути клубом, але також і сауною в майбутньому.
Пітер Б

13

Перший підхід вказує на первісну одержимість . Оскільки ви передаєте вставки та рядки навколо, програмісту дуже легко помилитися (наприклад, передати clubId параметру terminalId). Це призведе до важкого пошуку помилок.

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

Навіть так, я б все одно дивився string invoice. Чи справді рахунок-фактура є рядком? Що amountозначає? Це швидше грошова вартість.

Ви згадали у своєму запитанні "те, що надсилається по дроті, - це лише ідентифікатори". Це правильно, але не дозволяйте цій вимозі замутити ваш домен.

Найкраще пояснення, яке я бачив на користь такого підходу, було в правилі 3 « Об’єктна гігієніка» :

Інт сам по собі є просто скаляром, тому він не має ніякого значення. Коли метод приймає int як параметр, ім'я методу повинно виконувати всю роботу з вираження наміру. Якщо той же метод приймає за параметр Година, набагато простіше зрозуміти, що відбувається. Невеликі об'єкти, подібні до цього, можуть зробити програми більш рентабельними, оскільки неможливо пройти рік методом, що приймає параметр Hour. За допомогою примітивної змінної компілятор не може допомогти вам написати семантично правильні програми. З об’єктом, навіть маленьким, ви даєте і компілятору, і програмісту додаткову інформацію про те, що таке значення і для чого воно використовується.


Отже, другий підхід є кращим? навіть якщо є клубний об’єкт із заповненим лише властивістю id?
Мітір

Здається, що це випадковий блог. Немає жодних доказів, які б сказали, що краще. Кого справді цікавить те, що віддається перевазі? Робіть те, що працює для вас
Джеймс

@James На це питання немає остаточної відповіді, тим більше, що ОП не дало нам дуже багато контексту. Кожен, хто категорично стверджує, що один підхід є кращим, ніж інший, робить ОП сумлінною послугою. Не все це чорно-біле.
MattDavey

1
@James Я просто зазначив, що перший підхід дуже легко вводить важко знайти помилок. Я не кажу, що примітивні типи погані, але метою примітивних типів є створення значущих типів доменів. Використання їх поза цим контекстом - це саме визначення примітивного запаху коду одержимості.
MattDavey

5
@James: Те, що сказав MattDavey, є усталеним фактом. Він не каже, що рідні типи погані, про що він говорить, що це: someMethod (int, int, int, string, decimal) набагато складніше зрозуміти та використовувати клієнтом, ніж якийсь метод (Club, Terminal, Card, String) , десяткова)
c_maker

2

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

Якщо ви надсилаєте ідентифікатор, то обидві системи повинні бути щільно пов'язані з тим, що це означає. ClubID є ключовим у таблиці клубів. Більше того, і абонент, і абонент повинні домовитись про те, як називається таблиця Клуби і в якій базі даних знаходиться. Якщо ви не хочете або не можете накладати це обмеження, то ви передатимете об'єкт, використовуючи загальний опис, рідний, серіалізований, xml, ім'я = значення, іні файл :)

Це, як ви визначили, обійдеться вам «за провід». Уникнути цього просто відправлення ідентифікатора коштує вам в іншому місці. Тож, хто вам найменше шкодить, зараз (а може пізніше ...) є показником доброго та поганого.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.