Я бы на самом деле ожидал, что TO будет выглядеть примерно так:
class User
def increment_points!(points, increment_credits)
@points+=points if increment_credits
@points-=points unless increment_credits
end
end
class Activity
def increment_user_points!
@user.increment_points!(points, true)
end
end
Создание модуля для include
может создать больше сложности. И весь смысл Закона Деметры (мне больше нравится думать о нем как о руководстве ...) заключается в том, что вы должны иметь возможность делать все, что вам нравится, с внутренностями User
без необходимости переписывать много кода вне учебный класс. Ваш UserDelegator
модуль мало чем помогает - вы все равно можете переписать этот код, когда возитесь с внутренностями User
.
Но если бы это был я, я бы не стал беспокоиться об этом, если только вы не переписываете лот кода, чтобы внести простые изменения в User
. Может быть, это потому, что я привык к стилю кодирования ядра Linux, который регулярно нарушает закон Деметры:
static inline int need_reval_dot(struct dentry *dentry)
{
if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
return 0;
if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
return 0;
return 1;
}
В трех объектах :) и я не уверен, что код будет более разборчивым, если написано:
need_reval_dot(dentry) {
if(likely(!dentry_need_reval_dot(dentry))
return 0;
}
dentry_need_reval_dot(dentry) {
return superblock_need_reval_dot(dentry->d_sb);
}
superblock_need_reval_dot(sb) {
return fs_type_need_reval_dot(sb->s_type);
}
fs_type_need_reval_dot(s_type) {
return fs_flags_need_reval_dot(s_type->fs_flags);
}
fs_flags_need_reval_dot(fs_flags) {
return fs_flags & FS_REVAL_DOT;
}
Таким образом, я все в пользу следования рекомендациям по модерации - спросите себя, действительно ли ваши изменения приводят к более чистому, более понятному коду или просто следуют правилу ради следующих правил.