Как должна быть моя подпись метода сервиса?
Я использую Service Layer, и до сих пор я использовал ServiceObject (который реализует ArrayAccess, Iterator, Countable), но мне интересно, хорошие ли идеи.
Вы бы сделали:
ArticleService::createArticle($articleData, $userId);
или
ArticleService::createArticle(ServiceObject $data);
где $data
:
array(
'title' => 'Lorem ipsum',
'body' => 'Dolor sid amet',
'userId' => 55,
);
Служба ServiceObject имеет преимущество для предоставления общей подписи для каждого метода, однако иногда она не выглядит эффективной и широко не используется, она теряет свои интересы.
Любая обратная связь?
Ответы
Ответ 1
Измените его на:
ArticleService::createArticle($title, $body, $user_id);
Это очень ясно, что вам нужно для создания "Статьи".
"опции", такие как ваши $articleData
и $data
, невозможно разумно интерпретировать, и я бы посоветовал это сделать.
Избавьте свою идею от общего ServiceObject
, это на самом деле очень плохая идея. Ваши мотивы благородны, но это неправильное решение.
Если вам нужно больше убеждать, не стесняйтесь.
Ответ 2
Я думаю, что лучший подход здесь - иметь что-то вроде
$article = new Article;
$article->title = "Lorem ipsum"
$article->body = "Dolor sit amet"
$article->creator = $userID
ArticleService::createArticle($article)
Хотя предположительно "createArticle" больше не будет лучшим именем для этой функции, поскольку объект Article уже был создан. Вероятно, у вас есть что-то вроде ArticleService::publishArticle($article)
, хотя я не знаю, что вы делаете.
Вы хотите отделить построение своих данных (Article
) от его использования (ArticleService
).
То, что я действительно пытаюсь сказать, не делает аргумент createArticle общим массивом или "ServiceObject", оба из которых являются бесполезными абстракциями списков аргументов, делают его классом, который действительно представляет соответствующий объект.
Ответ 3
Я проголосовал за объект, так как завершение кода в сложных системах - это очень хорошая вещь, а также некоторые авто-валидации, так как когда вы знаете тип объекта, вы можете каким-то образом его проверить. Но если у вас нет сложной логики в createSomething, тогда массив также может поместиться.
Ответ 4
Второй способ лучше, у вас никогда не будет проблем с людьми, которые назовут ваш метод неправильным! Также гораздо легче читать и видеть, что требуется. Для меня как разработчика было бы ясно, что мне нужно передать объект типа ServiceObject
, а затем я начну искать документацию или пример или интерфейс этого класса. Но в первом примере я должен прочитать код createArticle
, чтобы выяснить, как будут обрабатываться оба параметра.
Второй подход также поможет вам сохранить ваш API/подпись чистым с течением времени. Когда в createArticle
требуются некоторые дополнительные данные, вы просто передаете их через ServiceObject
, и вам не нужно менять подпись!
Для первого примера может быть немного лучше подпись:
ArticleService::createArticle(array $articleData, $userId);
В этом случае $articleData
должен быть массивом. Это предотвращает ошибки. В параметрах функции PHP для кастинга могут использоваться только массивы и имена классов.
Ответ 5
Нет правильного пути, но я использовал бы ArticleService::createArticle($articleData, $userId);
в этом конкретном случае.
Я предполагаю, что статья имеет требуемое непустое свойство userId (которое вы получаете из контекста) и необязательные (не очень важные) данные контента, которые могут быть пустыми.
Таким образом, связь между статьей и объектами пользователя очевидна. Читаемость немного улучшена. Кроме того, вам необходимо полностью ознакомиться как с данными, так и с методом createArticle.
В качестве доказательства: сразу, когда я увидел ArticleService::createArticle($articleData, $userId)
, я понял, что делает этот метод и что ожидает входных данных, а второй меня озадачил.
Кроме того, если userId отсутствует, в этот момент вы получите сообщение об ошибке, если вы не вставляете его в базу данных, где, вероятно, вы получите ошибку SQL, которую намного сложнее отслеживать.
С другой стороны, в ZF довольно часто использовать массивы в качестве параметров, чтобы ваш код мог выглядеть в другом стиле.
Однако это в основном зависит от ваших предпочтений.
Ответ 6
Я думаю, что лучший подход - это инъекция объекта. Но почему там ServiceObject?
У вас есть метод createArticle, тогда было бы логичным передать объект статьи, нет?
Таким образом, проще организовать процесс проверки, вы можете просто пометить поля, которые вы хотите проверить в аннотациях.
Также это вопрос подхода, который вы используете. Если вы используете шаблон отображения данных в своих слоях услуг, вы должны явно передать ему объект.
С объектом у вас есть прозрачный и понятный интерфейс связи между вашими объектами.
С массивом не ясно, какой тип данных вы передаете, какие поля и т.д.