Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Don't be fooled, over use of roles is just as bad as over use of MI.

    I worry that perhaps your a little too blinded by the shiney right now. Now, it seems the BBC system your working on was full of MI, so in this case, yes it probably makes a lot of sense to go heavily with the roles. And DBIx::Class is also uses MI very heavily and the planned Mooseification of it involves converting much of that to roles. But there are some things that fit really nicely into the inheritance model and those things really should use inheritance and not be shoe-horned into roles. The more common case that I have found is that roles and inheritance are best when used together (right tool for the right job basically).

    Here is a simple scenario in which I think a combination of roles and inheritance make the most sense. Basically it is using roles to build the lower levels of your system and then inheritance in the higher levels.

    When building a larger system it is nice to be able to use roles for the lower level parts of the system to share behaviors. By behaviors I mean cross cutting behaviors that really do not make sense with inheritance. An example might be a HasDBICSchema role which provides access to a DBIx::Class schema object. Your web controller might need access to the schema as well as your maint scripts, to make these two different parts of your system share the a similar base class would probably not make much sense.

    Now, once you have your lower level components built, it is nice to then be able to use subclassing with these components for your specific tasks/needs. I say this because by the time you have these components all built your classes are probably fairly large and complex. Working with large roles and their flattened namespaces can get pretty hairy when you get to this level of your system design. You end up needing to do a lot of exclusion and aliasing, which in my opinion, is a code smell.

    In many cases, a simple subclass that overrides maybe one or two methods to add extra functionality is so much simpler and more maintainable then having to play composition games with multiple roles all the time. This is especially true if this is a living system where to do things with roles might require refactoring of the original code (we can't predict all possible needs and use cases). Sure, this might seem a little hackish to some, but elegance has to be balanced with risk when you have a live system running (and perhaps a limited budget).

    Basically I think it is best to ask yourself "Is this a true is-a relationship?". If the answer is "yes", then use inheritance. If your honest with yourself and think things through you should end up with a nice shallow inheritance hierarchy and a decent sized collection of behavioral roles.

    - Stevan

    • Thanks. I think that gives some great perspective on this. You had previously mentioned that overuse of roles was bad and I never asked you to follow up on your comment. I'll reread that paper (I read it years ago before I really was familiar with traits) and hopefully I'll have a better perspective now.