Single Responsible Principal (SRP)

For implementing any of the Design pattern we needs to follow some rules. One of the important rule for the Single Responsible Principal (SRP).

"The single responsibility principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility."

The responsibility(s) of an object should not be overlapped in to same level of abstraction. Each and every method should be focus on different aspects. If you implement a SRP principle properly then it will consider as a Functional unit.

Here is the below example explains what is the use of SRP. “Bankdetail” class is having different properties for Account information. Also it having the option for calculating interest for the account base on type.   
Example
/// <summary>
    /// Class of BankDetails Class
    /// </summary>
    public class BankDetail
    {
        public string AccountNo { get; set; }
        public string AccountName { get; set; }
        public string Type { get; set; }
 
        /// <summary>
        /// Return/Print Account Details
        /// </summary>
        public void GetAccountDetails()
        {
            Console.WriteLine( AccountNo +" : "+ AccountName);
        }
        /// <summary>
        /// Calculate interest Rate.
        /// </summary>
        public void CalculateInterest()
        {
            if (Type.Equals("1"))
            {
                Console.WriteLine(1000 * 8);
            }
            Console.WriteLine("Calculating Interest");
        }
    }
 

We can call the method like the following: 

     BankDetail bankdetails = new BankDetail();
            bankdetails.AccountName = "San";
            bankdetails.AccountNo = "10001";
            bankdetails.Type = "1";
 
            bankdetails.GetAccountDetails();
            bankdetails.CalculateInterest(); 

While closely watching the above implementation we can see the BankDetail class, it is holding two different Functionalities.  
1)      Bank Account Information.

2)      Interest Calculations.
So I am going to split the responsibility to differently based on the SRP Principles.

First I am separating Bank Account information:-

/// <summary>
    /// Bank information details
    /// </summary>
    public interface IBankInfo
    {
        string AccountNo { get; set; }
        string AccountName { get; set; }
        string Type { get; set; }
        void GetAccountDetails();
    }
    /// <summary>
    /// Interface implemention
    /// </summary>
    public class BankAccount : IBankInfo
    {
        public string AccountNo { get; set; }
        public string AccountName { get; set; }
        public string Type { get; set;
 
        public void GetAccountDetails()
        {
            Console.WriteLine(AccountNo + " : " + AccountName);
        }
    }
 
This unit used for only Account details information. Second I am going to split Interest calculation part.
/// <summary>
    /// Remove/Split interest Calculation 
    /// </summary>
    public interface IInterstCalculator
    {
        decimal CalculateInterest(IBankInfo backdeatils);
    }
    /// <summary>
    /// Inplement the Interface for Interest calculation.
    /// </summary>
    public class InterestCalculator : IInterstCalculator
    {
        public decimal CalculateInterest(IBankInfo backdeatils)
        {
            if (backdeatils.Type.Equals("1"))
            {
                return (decimal)(1000 * 8);
            }
            return 0;
        }
    }

This unit is only for interest calculation
Accessing SRP Units for getting the Non SRP implementation Output.
     BankAccount bankAcc = new BankAccount();
            bankAcc.AccountName = "santho";
            bankAcc.AccountNo = "10002";
            bankAcc.Type = "1";
            bankAcc.GetAccountDetails(); 
 
            InterestCalculator ical = new InterestCalculator();
            Console.WriteLine(ical.CalculateInterest(bankAcc).ToString());
Here we first create the Bank Account and then send the object for Interest calculation. This example is very small to understand to SRP widely. Assume that this implementation is in a large Banking application and we needs to change the Interest calculation part. The implementation will complete in Both SRP & NON SRP Implementations easily. But in NON SRP Impacted testing is very high.  
While writing a functionality, Split your code for avoiding dependency. Give a class only one Responsibility.

No comments:

Post a Comment