God Object - A Code Smell

Introduction 

The God object is a part of the code smell group and it is a kind of object that knows too much or does too much. That means a huge class in terms of number of lines of code. It is very famous in bad programming because it creates tight coupling and increases the challenges in the code maintainability. If a class contains too many functions or properties, then it increases the lines of codes in that class and this class will suffer from God Object,  a bad programming practice. It is a kind of an Anti-Pattern because it opposes a common design principle.

Two famous SOLID principles are "Single Responsibility" and "Interface Segregation." The main objective of these two principles is to separate the large solution into small pieces of logical code blocks with interfaces and classes. But, the God Object doesn't care about these principles. So, it enters into the category of anti-design pattern.

Below is an example of a class that is a God Object.
  1. using System;  
  2. namespace DelegateExample {  
  3.     public class EmployeeUtils {  
  4.         public void FetchEmployeeDetails(string employeeId) {}  
  5.         public void SaveEmployeeDetails(EmployeeModel employeeDetails) {}  
  6.         public void ValidateEmployeeDetails(EmployeeModel employeeDetails) {}  
  7.         public void ExportEmpDetailsToCSV(EmployeeModel employeDetails) {}  
  8.         public void ImportEmpDetailsForDb(EmployeeModel employeeDetails) {}  
  9.         private class EmployeeModel {  
  10.             public string EmployeeId {  
  11.                 get;  
  12.                 set;  
  13.             }  
  14.             public string EmployeeName {  
  15.                 get;  
  16.                 set;  
  17.             }  
  18.             public string EmpplyeeAddress {  
  19.                 get;  
  20.                 set;  
  21.             }  
  22.             public string EmployeeDesignation {  
  23.                 get;  
  24.                 set;  
  25.             }  
  26.             public double EmployeeSalary {  
  27.                 get;  
  28.                 set;  
  29.             }  
  30.         }  
  31.     }  
  32. }  

 The EmployeeUtils class above contains three major design smells.

  • Violation of Single Responsibility Principle 
    This class is doing everything. The functionalities of class should be separated into other different classes and interfaces based on similar type of responsibilities. It will remove the issue of tight coupling and will be easy for maintainability.
  • Opposing Design Pattern
    It is not following any design pattern principle. Code can't be reused. It is prone to copy-paste for the same.
  • Missing Abstraction
    This class is missing an abstraction, so writing unit tests will be very difficult. It will expose all members of class.

Solution of the above God Object class 

It should follow the SOLID Principle. Interface segregation will be a very good solution for this class.
 
Create separate Model class for the "EmployeeDetails" like below.

  1. public class EmployeeModel  
  2. {  
  3.     public string EmployeeId { getset; }  
  4.     public string EmployeeName { getset; }  
  5.     public string EmpplyeeAddress { getset; }  
  6.     public string EmployeeDesignation { getset; }  
  7.     public double EmployeeSalary { getset; }  
  8. }  

Divide functionalities into different classes and interfaces, like below.
 
Import Export

  1. public interface IImportExport  
  2. {  
  3.     void ExportEmpDetailsToCSV(EmployeeModel employeDetails) { }  
  4.     void ImportEmpDetailsForDb(EmployeeModel employeeDetails) { }  
  5. }  
  6.   
  7. public class ImportExport  IImportExport  
  8. {  
  9.   
  10. }  

Database operation for employee 

  1. public interface IEmployeeDbOperations  
  2. {  
  3.     void FetchEmployeeDetails(string employeeId) { }  
  4.     void SaveEmployeeDetails(EmployeeModel employeeDetails) { }  
  5. }  
  6.   
  7. public class EmployeeDbOperations  IEmployeeDbOperations  
  8. {  
  9. }  

Validation operation for employee

  1. public interface IEmployeeValidation  
  2. {  
  3.     void ValidateEmployeeDetails(EmployeeModel employeeDetails) { }  
  4. }  
  5.   
  6. public class EmployeeValidation  IEmployeeValidation  
  7. {  
  8. }  
Class Diagram
 

Symptoms of God Object

Below are the common symptoms of God Object

  • Very large class, containing too many methods and properties.
  • SOLID Principle is not being followed.
  • Keeping all complexities in one place
  • Design Pattern is not followed, and advocates for  Anti-Pattern.
  • Tight coupled functionalities.
  • Doesn't believe in Divide and Conquer Strategy. 

Problems with God Object

The below problems are faced when we encounter God Object.

  • All unwanted members of God object class will inherit to other class during inheritance. So, it does not fit for re-usability. 
  • Object will be very large, so it will be very expensive in memory.
  • It will use more unwanted resources even for the simple operation.
  • It will create the issue of tight coupling so it will be difficult to maintain and enhance.
  • Unit test writing will be very difficult. 

How to refactor God Object class?

God object can be refactored and fixed. Below are the ways.

  • Try to use "Interface Segregation" principle and delegate calls to the new extracted classes.
  • Write unit test for each method.
  • Use separate model classes for fields or properties.
  • Don't make methods large. Divide into different logical methods.
  • If module is large, then try to use any design pattern.
Conclusion

God Object is a kind of anti-pattern. It opposes the design pattern. It spoils the code and makes the enhancement, unit test, and re-usability part very difficult. It is very expensive to load into memory.