Наши команды проводят следующую дискуссию:
Допустим, у нас есть два следующих метода:
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);
то, что отправлено по проводам, это просто идентификаторы.
одна сторона говорит, что первый метод правильный, потому что у нас есть только идентификаторы терминала и клуба, и должно быть ясно, что у нас больше ничего нет, это мой подход.
другая сторона говорит, что второй метод правильный, потому что он более гибкий.
Мы знакомы с идеей параметров объекта, другая сторона также считает, что параметр объекта должен иметь объекты в качестве свойств.
Какой правильный подход?
Может быть, есть третий, еще лучший подход?
Ответы:
Ответ зависит от контекста.
Если ожидается, что клиент будет иметь все эти объекты уже доступны , я бы использовал параметры объекта. В противном случае их код будет выглядеть более запутанным, чем это должно быть. (Например, у них будут звонки как
club.getId()
, например.)Если у клиента будут легко доступны только идентификаторы , тогда, возможно, второй подход лучше, так как вы можете не захотеть, чтобы клиент собирал / загружал все эти объекты, если вам действительно нужны только идентификаторы.
Один из вариантов - предоставить оба метода , чтобы клиент мог выбрать, какой из них использовать (учитывая, что это не загромождает ваш API).
В общем, параметры объекта являются более расширяемыми, так как если в будущем вам понадобится другой кусок данных для выполнения работы, вам не нужно вводить другой метод, который получает эту дополнительную информацию.
Наконец, подписи вашего метода не должны быть продиктованы спецификой того, что делает метод (в вашем случае, что именно идет по проводам). API должен иметь абстрактный смысл, поэтому, если реализация изменится, вы не облажались.
источник
Первый подход свидетельствует о примитивной одержимости . Поскольку вы передаете ints и строки, программисту очень легко ошибиться (например, передавая clubId в параметр TerminalId). Это приведет к трудностям поиска ошибок.
Во втором примере невозможно пропустить клуб, когда ожидается терминал - это даст вам ошибку времени компиляции.
Несмотря на это, я все равно посмотрю
string invoice
. Счет действительно является строкой? Чтоamount
значит? Это, скорее, денежная стоимость.Вы упомянули в своем вопросе «то, что отправлено по проводам, это просто идентификаторы». Это правильно, но не позволяйте этому требованию запутать ваш домен.
Лучшее объяснение, которое я видел в пользу этого подхода, было в правиле 3 Object Calisthenics :
источник
Там нет правильного ответа на этот. Любой вариант может быть правильным для работы. Ну, в любом случае, аргумент в счет-фактуре вызвал у меня на лбу борозду, я понятия не имею, что это такое от чтения кода.
Если вы отправляете идентификатор, то обе системы должны быть тесно связаны с тем, что это представляет. ClubID является ключевым в таблице клубов. Более того, и вызывающему, и вызываемому абоненту необходимо согласовать, как называется таблица «Клубы» и в какой базе данных она находится. Если вы не хотите или не можете наложить это ограничение, тогда вы передадите объект, используя некоторое общее описание, родной, сериализованный, xml, name = value, ini-файл :)
Это, как вы определили, будет стоить вам «по проводам». Избежать этого, просто отправив идентификатор, стоит в другом месте. То, что причиняет вам боль меньше всего, сейчас (или может быть позже ...) является показателем хорошего против плохого.
источник