Rails, сервисные объекты: передать весь объект или просто ID
Я реорганизую приложение в сервисные объекты, чтобы уменьшить размер моделей и упорядочить фактические файлы кода.
Для этого я использую сервисные объекты, которые выполняют действия над данным объектом. Однако одна из дилемм, с которыми я сталкиваюсь, заключается в том, передам ли я весь объект службе или просто ID.
Классическим примером является обновление адреса электронной почты пользователя. Причина, по которой я бы использовал сервисный объект вместо простого метода в модели, заключается в том, что это электронное письмо также должно синхронизироваться с внешними сторонними системами, которые не принадлежат пользовательской модели.
class User::UpdateEmail
# Passing entire user object
def self.update_for_user(user, new_email)
if user.update_attributes(email: new_email)
# do some API calls to update email in external services
true
else
false
end
end
# Just passing user ID
def self.update_for_user_id(user_id, new_email)
user = User.find(user_id)
if user.update_attributes(email: new_email)
# do some API calls to update email in external services
true
else
false
end
end
end
Есть ли какая-то польза от одного против другого? Кажется, что они оба "делают" одно и то же, и это выглядит как личное предпочтение для меня, но мне любопытно, если бы я столкнулся с ситуацией, когда я передаю весь пользовательский объект, и каким-то образом он устаревает, пока объект службы работает в теме.
Если я передам всего пользователя, то класс, который вызывает объект службы, должен будет выполнить проверку, чтобы убедиться, что пользователь существует и т. Д., Тогда как если я просто передам user_id, то объект службы теперь должен обеспечить действительный объект, и т.п.
Существует ли согласованный или ожидаемый стандарт или шаблон для этого типа сервис-ориентированной операции? Я хочу убедиться, что я использую последовательный подход во всем приложении, а также не ввязываться в дыру позже.
0 ответов
Ну... это зависит:
Если вы используете фоновые задания, вы должны передавать только идентификаторы! Если вы этого не делаете... возможно, возражаете и всегда спрашиваете себя, кто / что за это отвечает.
Если объект, которому вы передаете вещь, является ответственным и должен знать об этом, то, возможно, этот объект должен позаботиться о его поиске, и будет достаточно просто идентификатора. Поиск будет происходить в этом ответственном объекте.
Если объект, которому вы передаете вещь, принимает любой объект и не заботится о его типе, потому что он обрабатывает его динамически. (как он есть) тогда, возможно, весь объект. в зависимости от того, насколько он большой...
Вы должны суметь судить об этом деле в каждом конкретном случае, нет 1-general-rule-or-solution
за исключением того, что каждый объект должен нести единственную ответственность. И даже это можно согнуть или сломать в рубине
В общем:
Постарайтесь, чтобы вещи были слабо связанными, ясными и простыми, с каждой отдельной ответственностью. Избегайте связывать воедино вещи, которые не должны знать друг о друге или быть связанными вместе.
Рекомендую прочитать:Practical Object-Oriented Design
in Ruby, автор: Sandy Metz.
В нем есть хорошие примеры и ясно объясняются эти концепции.