Home Architecture Cohesion And Coupling – Approach for Design

Cohesion And Coupling – Approach for Design

by Dhanik Lal Sahni

Cohesion and Coupling are essences of a good design process. The system should be decomposed into many modules to make it manageable in system changes. Projects which are well-designed are rarely in trouble in system changes. These changes should be properly reviewed and recognized.

If software system is not properly modularized, then it will create problem when sytems changes are required. A good software design help in clean decomposition of a problem into modules and arrangement of these modules. Therefor system analyst, should must design application with goal of high cohesion and low coupling.

As this topic is big for clarification, we have divided it into two parts.

Second part of this is available here

Cohesion

Cohesion is a measure of how closely related the members (classes, methods, functions within a method) of a module are to the other members of the same module. It is always advisable that components should contain only functionality specifically related to that component.It indicate the degree which a class has a single well focused purposed. The more focused a class is, the higher its cohesiveness.

When we work on big project,we can find different kind of Cohesion in the system. Let us have a look on these types to better understand this.

Low Cohesion (Highly Undesirable)

Modules with low levels of cohesion are highly undesirable and should be modified or replaced.

Coincidental Cohesion

There are situation when developer add many funcions in on class, just to group them. There is no similarity in the function. This is called Coincidental cohesion. An example of this could be a Utility class where elements are completely independend of each other. We group them in utility class so that any other class can use.

Below class has three functions SendEmailNotification, PrepareCustomerObject and PrintCustomerReport. These functions are not related to each other, but these are grouped in one Helper Class so that other can use them when required that functionality.

    public class Helper
    {
        public bool SendEmailNotification()
        {
            // Sending Email Login
            return true;
        }
        //Prepare Cutsomer Object Before Saving
        public Customer PrepareCustomerObject(Customer customer)
        {
            return customer;
        }
        //Customer Report
        public void PrintCustomerReport(string customerId)
        {
            // Logic For Customer data Print
        }
    }

To easily maintable code, these three function should be created in seprate helper class. We can also put these in resptected class as these will be called from there only.

        
    public class EmailHelper
    {
        public bool SendEmailNotification() 
        {
                // Sending Email Login
                    return true;
        }
    }
    public class CustomerHelper
    {
        public Customer PrepareCustomerObject(Customer customer)
        {
            return customer;
        }
        public void PrintCustomerReport(string customerId)
        {
            // Logic For Customer data Print
        }
    }

Logical cohesion

Logical cohesion is when parts of a module are grouped because they are logically categorized to do the same thing, even if they are different by nature.

    public class Report
    {
        public void PrintAll(int flag)
        {
            if (flag == 1)
            {
                //LocalSalesReport Logic
            }
            else if (flag == 2)
            {
                //RegionalSalesReport();
            }
            else if (flag == 3)
            {
                //NationalSalesReport();
            }
            else if (flag == 4)
            {
                //InternationalSalesReport();
            }
        }

If user want national sales report then he has to pass flag value 3 to function. This will print require report. Complete code is written in one fuctions, so even though we require LocalSalesReport, we have to call PrintAll. This can be changed like below to call specific function, instead of calling with argument.

    public class Report
    {
        public void PrintAll()
        {
           LocalSalesReport();
           RegionalSalesReport();
           NationalSalesReport();
           InternationSalesReport();
        }
        public void LocalSalesReport()
        {
            //Business Logic
        }
        public void NationalSalesReport()
        { 
            //Business Logic
        }
        public void RegionalSalesReport()
        {
            //Business Logic
        }
        public void InternationSalesReport()
        {
            //Business Logic
        }
    }

Temporal cohesion

Temporal cohesion is when parts of a module are grouped into a procedure and executed together during the same time-frame. When we create Window Services, we need to initialize some objects to be used by application at runtime.

    public class Temporal
    {
        ILogger logger = null;
        public readonly string ApplicationName;
        public Temporal()
        {
            logger = new Logger();
            ApplicationName = "Temporal";
            //other initialization Logic
        }
        ~Temporal()
        {
            logger = null;            
        }
    }

Instead of initializing code in constructor, we should initialize code using properties. So that object will be initialized when property is called.

    public class Temporal
    {
        ILogger logger = null
        public readonly string ApplicationName;
        public Temporal()
        {           
        }
        public ILogger Logger
        {
            get
            {
                if (logger == null)
                    logger == new Logger();
                return logger;
            }
        }
        ~Temporal()
        {
            if(logger != null)
                logger = null;
        }
    }

Moderate Cohesion (Acceptable)

Modules with moderate cohesion are acceptable, but not ideal. We should consider modifying them, but that changes might introduce other design problems, so we might have to leave these as they are.

Procedural Cohesion

This type of Cohesion is supported in module where set of activity need to be done one after another. That activities may be unrelated. Let us take example of folllowing module where sql query is execute using ADO.NET classe.

  • create connection string
  • Open connection using SqlConnection class
  • Execute sql command suing SqlCommand
  • Get resultset using SqlDataReader

In this example record is fetched from database. We have to use SqlConnection, SqlCommand, SqlDataReader which is different in terms of functionality. But all of them make a complete procedure to get records from database.

    public void ExecuteQuery()
    {
        if (OpenConnection())
        {
            if (ExecuteQuery(command, "select * from product"))
            {
                CreateResult(dataset);
            }
            CloseConnection(connection);
        }
    }
    public bool OpenConnection()
    {
        //Logic for SQL Connection 
        return true;
    }
    public DataSet ExecuteQuery(SqlCommand command, string query)
    {
        //Logic for Command execution 
        return new DataSet();
    }
    public DataTable CreateResult(DataSet dataAdapter)
    { 
        //Logic for result creation
        return new DataTable();
    }
    public bool CloseConnection(SqlConnection connection)
    {
        //logic to close connection
        return true;
    }

Sequential Cohesion

This type of Cohesion is supported in module where set of activity need to be done one after another. That activities must be related to each other. Let us take example of folllowing module where student GPA score is prepared based on marks.

  • Add individual mark of each subject
  • Calculate GPA score
  • Calculate cumulative GPA score

Above listed activity can be clubed in one function as input for all is student grade record.

    public float CalculateGPA()
    {
        AddStudentScore(record);
        CalculateSemesterGPA(record);
        CalculateCumulativeGPA(record);
    }
    public void AddStudentScore(StudentRecord record)
    {
        //Add Calculation Logic
    }
    public void CalculateSemesterGPA(StudentRecord record)
    {
        //Add Calculation Logic
    }
    public void CalculateCumulativeGPA(StudentRecord record)
    {
        //Add Calculation Logic
    }

Communicational Cohesion

A module exhibits communicational cohesion if all the activities it supports use the same input or output data or it access and modify the same part of a data structure. Let us take an example of online book buying set where user can search books with different criteria. After searching, it show detail like following

  • Find Title of Book
  • Find Price of Book
  • Find Publisher of Book
  • Find Author of Book
    public void SearchBooks()
    {
        BookQuery query = new BookQuery();
        query.category = ".NET";
        FindBookTitle(query);
        FindBookPrice(query);
        FindBookPublisher(query);
        FindBookAuthor(query);
    }
    public void FindBookTitle(BookQuery query)
    {
        //Logic here
    }
    public void FindBookPrice(BookQuery query)
    {
        //Logic here
    }
    public void FindBookPublisher(BookQuery query)
    {
        //Logic here
    }
    public void FindBookAuthor(BookQuery query)
    {
        //Logic here
    }

High Cohesion (Desirable)

Modules with high cohesion are extremely desirable, and don’t need to be changed.

Functional Cohesion

A functionally cohesive module is one in which all of the elements contribute to a single, well-defined task. Simply put, functional cohesion is when a function does only one thing. Let us take example of Math class in C#. Functions like Min, Max, Pow, Avg, Round,Sqrt all are focused on one task.

Continue the second part of this topic.

You may also like

Leave a Comment