Search code examples
oopsingle-responsibility-principlevisitor-pattern

In OOP, is it necessarily favorable to have more classes with fewer methods rather than fewer classes with more methods?


I've been studying design patterns, and I've come across the Visitor Pattern. It's a really strange thing to me; it seems as if its only purpose is to prevent the original classes in the hierarchy from needing to change even when a new responsibility is added to them. This happens simply by delegating those responsibilities to an implementation of an abstract visitor class (or interface) and effectively double dispatching to call the operating function of the correct visitor passing in the correct dynamic type.

I've looked into various other questions discussing when and why to use the Visitor Pattern, and all I've come across is that in OOP, it is expected that your number of classes grow rather than the number of methods per class, which the Visitor Pattern specializes in.

However, is this true? This sounds like a gross oversimplification of OOP to me. For reference, this answer came from here

I also read another (loosely) related question here, the answers to which imply that you should only create more classes and separate responsibilities where it makes sense. Does it really make sense to organize your code such that a "responsibility" of a class is defined merely by a single operation, regardless of the type being operated on (i.e. a visitor is responsible for the implementation of the operation for every relevant type), or does it make much more sense to define a responsibility as a set of operations which can be done on a single type (delegate those responsibilities to the types themselves)?

If the goal is merely to reduce lines of code in each class, why is this a legitimate goal? Line count alone does not have any direct implications regarding encapsulation, modularity, code organization, or general good OOP practices, right?

Edit: I now understand that patterns do not exist to serve OOP, and I now understand that there are cases where the Visitor pattern is the best solution. That being said, does it, or does it not, promote less sensible class hierarchies when used alongside OOP?


Solution

  • I think you might have misunderstood what the Visitor Pattern, and Patterns in general do and why we sometimes use them.

    It isn't because of some OOP thing, some abstract concept or some hidden truth. It's quite the opposite. You are expected to model your problem in a proper object-oriented way, using objects with behavior, hidden state, all that. That is OO in a nutshell. You are not supposed to go out and look for patterns to apply randomly in your code, in fact that would be an anti-pattern in itself :)

    Now, some people noticed, that there are certain small problems to which most of us tend to produce similar solutions. These are interesting, not because the solutions are so ground-breaking, or valuable on their own, but because it just spares us some time and brainpower not to solve these over and over again. These are the Patterns.

    Back to your question: If you don't quite understand what the Visitor Pattern does or why it does that, or how/why one would use it, don't worry about it. If you come across a problem that needs it, you will notice! That is the situation where nothing else will quite work, and you will essentially have to use it. In all other situations you shouldn't use it!

    Summary: No, we don't use the Visitor Pattern because of some OOP thing. Reducing lines it not a legitimate goal in itself. Yes, line count alone doesn't impact encapsulation, modularity, etc.