7

So, I am now dealing with this relatively new codebase which uses, and sometimes feels like it abuses traits. Since I have been exposed to trait usage in a rather limited fashion, I was wondering whether the way they are using them makes sense. I believe they are preferring to use traits when good old inheritance would work just as well.

Here is an example of what I am talking about:

trait CrudTrait
{
  use FindTrait;
  use ExistsTrait;
  use UpdateTrait;
}

Then, the trait is used more or less the following fashion:

class <EntityName>ServiceAbstract extends ServiceAbstract 
{
  use CrudTrait;
}

I can't think of a reason why something like this is necessarily better than just making such methods class members. At the end of the day, these particular traits are designed in such a way that they cannot be re-used horizontally.

Is there any reason why this could better than just attaching the methods to the parent class of the hierarchy?. I am starting to believe that trait abuse could be a code smell here.

1
  • I would argue that as long a the traits are self-contained (doesn't rely on properties in their specific use classes) this is fine. If they do, however, rely on properties defined inside other traits/classes I would consider them as abused.
    – AnotherGuy
    Commented Sep 18, 2015 at 16:10

2 Answers 2

7

Composition is usually preferable to inheritance, unless you need substitutability. Traits are one specific way to perform composition. Usually you use traits when you need horizontal reusability, but it's also reasonable to use them for modularity, to break up a class that can't be broken up for some reason.

It's relatively rare that you can't just split up the class normally. It's usually driven from an external requirement, like needing to provide all the parts of an API in one class. Alternately, traits are often used to sort of assemble a compile-time configuration of a class, such as if you had multiple choices for a FindTrait, for example, that different customers would choose differently, even if your particular implementation only uses the one configuration.

Traits are probably under-utilized and not very well understood, because a lot of programmers' first and main languages don't have them. They could well be abused in this particular code base. However, in general, inheritance is much more likely to be overused than traits. If traits are being used improperly here, it's highly likely that replacing it with inheritance would make it worse.

1

From what you've described, I'd have to agree that inheritance seems like a better approach. But that opinions is based on knowing virtually nothing about the code base.

Traits essentially provide a way to do "multiple inheritance", and yes it can sometimes be useful. Say for example you have a child class already inheriting from a parent, but there is another core set of functionality that needs to be shared all throughout the inheritance tree.

If the problem can be solved with inheritance alone though, that should always be your first choice.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.