I'd actually expect TO to look more like this:
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
Creating a module to include
would seem to create more complexity. And the whole point of the Law of Demeter (I like to think of it more as a guideline..) is that you ought to be able to do whatever you like to User
's internals without having to rewrite much code outside the class. Your UserDelegator
module doesn't help much -- you still get to re-write that code when you fiddle with User
's internals.
But if it were me, I don't think I'd even bother with this, unless you're finding yourself rewriting a lot of code to make simple changes to User
. Maybe that's just because I'm used to the Linux kernel coding style, which breaks the law of Demeter on a regular basis:
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;
}
Three objects away :) and I'm not sure the code would be more legible if written:
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;
}
So I'm all in favor of following guidelines in moderation -- ask yourself if your modifications actually lead to cleaner, more maintainable code, or if it is just following a rule for the sake of following rules.