Sunday, April 01, 2007

Ruby: [Anti-pattern] Extract Module to shorten Class Definition

A Ruby module can be used to encapsulate a role that an object might play. For example, if an object wants to delegate, it can extend Forwardable.

Unfortunately, more than once I've seen an (anti)pattern of methods being moved into a module to shorten a class definition. This anti-pattern can be fairly easy to spot.
  • Do you have a module that only one class includes (or extends).
  • Do you have a module that requires other methods to be defined on the class that includes it.
I understand the motivation, when the class definition is getting a bit long and hard to follow it might make sense to take a group of similar methods and move them to a module. The problem with this refactoring is that it is possibly making the situation worse. If a class definition is already beginning to run long, it's possible that the class may be doing too much. Simply moving behavior into a module will not address this problem, and now if someone wants to see what an objects responsibilities are they have to look in more than one place.

A better solution could be to extract a class that encapsulates a subset of the responsibilities. If the behavior is required in various classes then it's probably time to look at converting the class to a module.
Post a Comment