Добавить ярлыки или следовать семантике ActiveRecord? - PullRequest
1 голос
/ 08 февраля 2009

Еще один спор с моим другом. Рассмотрим этот код:

class User < ActiveRecord::Base
  has_many :groups
  def in_group?(group)
      groups.include?(group)
  end
end
class Group < ActiveRecord::Base
  has_many :members
  def add_user(user)
      members << user
  end
end

Мое мнение таково, что эти методы добавляют дополнительную ненужную сложность к коду и трудно угадываются - например, почему #in_group? но не #is_a_member_of ?, или почему #add_user, а не #add_member и т. д. Исходя из моего 4-летнего опыта работы с Rails и общего 20-летнего опыта программирования, мне лучше следовать семантике AR и использовать User # groups.include? (Group) и Group # members << user. Они легко угадываются, и в случае, если мне понадобятся дополнительные функции, я могу использовать обратные вызовы для has_many: members и переопределить User # groups.include? в модуле расширения ассоциации, если это будет необходимо. </p>

Однако мой друг утверждает, что для создания «точек абстракций» лучше использовать ярлыки, и лучше расширять этот код, а не использовать обратные вызовы или перегрузки.

Что вы думаете?

P.S. просто чтобы быть ясно, я ненавижу подход "ЧТО, ЕСЛИ":)

Ответы [ 5 ]

2 голосов
/ 08 февраля 2009

Я полностью согласен, что эти методы не должны быть добавлены. Это не работа моделей для создания других связанных объектов. Это работа доверенного лица ассоциации. Я бы также остерегался переопределения поведения прокси-серверов ассоциации, поскольку вы склонны видеть некоторые странные побочные эффекты из-за способа реализации прокси.

1 голос
/ 08 февраля 2009

Я определенно за абстракцию, но не в этом исполнении. Ваш друг поднимает вопрос: что, если вы определите, изменится ли член группы? У вас есть тонна рефакторинга, удачи в этом!

Тем не менее, я вижу аргумент о размещении непонятных функций в неправильных местах. Я бы сказал, что у вас неправильная организация, почему бы не присоединить их к конкретному объекту модели отношений?

пример:

user.groups.in_group?("admin")

или

group.members.add_user(user)

Это выглядит намного элегантнее, немного более многословно, но ваше разделение более актуально.

1 голос
/ 08 февраля 2009

Стиль, который вы цитировали, защищен в соответствии с «Законом Деметры», который предостерегает от манипулирования клиентским кодом groups или members напрямую.

0 голосов
/ 09 февраля 2009

Я поддерживаю эти методы, когда есть причина (например, «член» в группе меняет значение). Наличие этих методов инкапсулирует логику, которая будет расти и изменяться со временем, и помогает в тестировании. Разве это не весь смысл ОО программирования?

0 голосов
/ 08 февраля 2009

Для in_group?: название вашего метода можно угадать в одном направлении - совершенно очевидно, что он делает, когда вы читаете его. Это важный вид догадок. Когда кто-то поддерживает этот код, он не будет пойман на вызове in_group?. Это также более декларативно и кратко, что улучшает удобочитаемость (в данном случае незначительно, но, как правило, хорошо). Это метод Smalltalky.

С другой стороны, я думаю, что метод add_user не нужен. Это не кажется особенно кратким или прямым, просто нестандартным. Название все еще довольно очевидно и не слишком вредно, но я не вижу в этом пользы. Похоже, что это скорее живописный маршрут, чем ярлык.

...