Ruby classes should have methods and data that relate to the central purpose of the class. Classes should have a single purpose, so they can be described in a single sentence without using “and” or “or”. Single purposes classes with methods that all relate to the central purpose of the class are easier to maintain, test, and reuse.
The following pseudocode illustrates a multipurpose class.
class Comment def initialize(title, body, likes, parent_post_id) @title = title @body = body @likes = likes @parent_post_id = parent_post_id end def self.most_popular # returns the comment with the most likes end def export_to_csv # contains CSV specific logic end def title_of_parent_post # fetches the parent post and parses the parent object for the title end def establish_connection_with_trello_api # uses API key to connect with Trello API end end
The single purpose of the Comment class is to create a comment that keeps track of the title, body, likes, and parent_post_id. The Comment#most_popular method finds the instance of the Comment class with the most likes and this is related to the central purpose of the Comment class. The Comment#export_to_csv converts a Comment object to a CSV file is appropriate for the Comment class, but any CSV specific logic should be included in a separate class. The Comment#title_of_parent_post method is on shaky ground since it seems more appropriate to ask the Post object directly for its title than to ask the Comment class. The Comment#establish_connection_with_trello_api method is unambiguously misplaced as the Comment class should have nothing to do with API configuration.
Interrogating your class and assessing the reasonableness of the questions is one technique to gauge if the behavior of the class relates to its central purpose.
1. Comment class, can you please tell me your most popular comment? -> This is a reasonable question for the Comment class
2. Comment class, can you please use an API key to establish a connection with the Trello API? -> The Comment class should have nothing to do with the Trello API – this method belongs elsewhere.
When all the methods in a class relate to the class’s central purpose, it is called highly cohesive. Highly cohesive classes with single purpose methods are self-documenting and easy to read, maintain, and test. When coding, it is tempting to put a single unrelated method in a class, but resist the urge because it is a slippery slope to add another unrelated methods. Good code and single purpose classes require strict discipline.