Skip to main content

Granularity and Cohesion

Granularity and cohesion are key concepts in software design that influence how you structure your code. They impact readability, maintainability, and the overall design quality of your software.

1. Granularityโ€‹

Granularity refers to the level of detail or size of the components in your software. It can apply to functions, modules, classes, or even entire services. Granularity is often discussed in terms of "fine-grained" or "coarse-grained" components:

  • Fine-grained components are small, with very specific responsibilities.
  • Coarse-grained components are larger, with broader responsibilities.

Example: Consider a library management system.

  • Fine-grained approach: You might have individual methods like addBookToCatalog(), removeBookFromCatalog(), updateBookDetails(), etc. Each function does one specific task.

    def addBookToCatalog(book):
    # code to add a book to the catalog

    def removeBookFromCatalog(bookId):
    # code to remove a book from the catalog

    def updateBookDetails(bookId, details):
    # code to update book details
  • Coarse-grained approach: You might have a single method manageCatalog(action, book) that handles multiple actions such as adding, removing, or updating books.

    def manageCatalog(action, book=None, bookId=None, details=None):
    if action == "add":
    # code to add a book to the catalog
    elif action == "remove":
    # code to remove a book from the catalog
    elif action == "update":
    # code to update book details

Pros and Cons:

  • Fine-grained: Easier to test and reuse but may lead to many small functions, making the code harder to follow.
  • Coarse-grained: Easier to manage as a whole but can become complex and harder to test.

2. Cohesionโ€‹

Cohesion refers to how closely related the responsibilities of a single module or class are. High cohesion means that the components of a module or class are highly related and focused on a single task or purpose.

  • High cohesion: All elements within a module or class work together to achieve a common goal. This usually makes the code easier to maintain and understand.
  • Low cohesion: The elements within a module or class are not closely related, which can lead to confusion and difficulty in maintaining the code.

Example: Letโ€™s continue with the library management system.

  • High cohesion: You create a CatalogManager class that focuses only on catalog managementโ€”adding, removing, updating books.

    class CatalogManager:
    def addBook(self, book):
    # code to add a book to the catalog

    def removeBook(self, bookId):
    # code to remove a book from the catalog

    def updateBookDetails(self, bookId, details):
    # code to update book details
  • Low cohesion: You create a LibraryManager class that handles catalog management, member management, and loan processing.

    class LibraryManager:
    def addBook(self, book):
    # code to add a book to the catalog

    def removeBook(self, bookId):
    # code to remove a book from the catalog

    def updateBookDetails(self, bookId, details):
    # code to update book details

    def registerMember(self, member):
    # code to register a new member

    def processLoan(self, memberId, bookId):
    # code to process a loan

Pros and Cons:

  • High cohesion: Easier to understand, test, and maintain. Changes to one aspect of the system (e.g., catalog management) donโ€™t affect unrelated parts.
  • Low cohesion: Can lead to "god classes" that do too much, making the code harder to maintain and more prone to errors when changes are needed.

Conclusion

  • Granularity helps determine how you break down your system into components. Fine-grained components are more specific and easier to reuse but can make your system more complex. Coarse-grained components are broader and simpler to manage but can become monolithic.
  • Cohesion ensures that your components are well-defined with a clear purpose. High cohesion is desirable because it makes your code more maintainable and understandable.

Balancing granularity and cohesion is key to designing robust, maintainable software. Fine-grained components with high cohesion often result in the best design, but itโ€™s important to strike the right balance based on the specific needs of your project.