Introduction to SOLID Principles

Last Updated: Jun 2, 2024

Bengali

The SOLID principles are a set of five design guidelines that help software developers create more maintainable, scalable, and robust code. These principles, introduced by Robert C. Martin (also known as Uncle Bob), are fundamental in object-oriented design and programming. They serve as a foundation for good software architecture, ensuring that code is easier to understand, modify, and extend.

 

What are the SOLID Principles?

 

  1. Single Responsibility Principle (SRP): A class should have only one reason to change, meaning it should have only one job or responsibility.

  2. Open/Closed Principle (OCP): Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.

  3. Liskov Substitution Principle (LSP): Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.

  4. Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use. Rather than one fat interface, many small, specific interfaces are preferred.

  5. Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

 

Real-Life Example: A Library Management System

 

Consider a library management system that handles various functions like issuing books, returning books, and calculating fines. Let's see how each SOLID principle applies to this system:

 

  1. Single Responsibility Principle (SRP):

    • Bad Example: A single class LibraryManager handles book issuance, returns, fine calculation, and member management.

    • Good Example: Separate classes are created for each responsibility:

      • BookIssueService for issuing books.

      • BookReturnService for returning books.

      • FineCalculator for calculating fines.

      • MemberManager for managing library members.

         

  2. Open/Closed Principle (OCP):

    • Bad Example: To add a new type of book, you modify the LibraryManager class, risking breaking existing functionality.

    • Good Example: Use an interface Book and have different implementations like PrintedBook and EBook. New book types can be added without modifying the LibraryManager class, which uses the Book interface.

       

  3. Liskov Substitution Principle (LSP):

    • Bad Example: A subclass SpecialBook changes the behavior of the base class Book in a way that existing functionality relying on Book breaks when using SpecialBook.

    • Good Example: Ensure that SpecialBook behaves in a way that any instance of Book can be replaced with SpecialBook without altering the correctness of the program.

       

  4. Interface Segregation Principle (ISP):

    • Bad Example: A large LibraryInterface includes methods for issuing books, returning books, calculating fines, and more, forcing all clients to implement methods they don't need.

       

    • Good Example: Create smaller, specific interfaces:

      • IssueService with methods related to issuing books.

      • ReturnService with methods related to returning books.

      • FineService with methods related to fine calculations.

         

  5. Dependency Inversion Principle (DIP):

    • Bad Example: High-level class LibraryManager directly depends on low-level class Database, making it difficult to change the database implementation.

    • Good Example: LibraryManager depends on an abstraction DatabaseService. Concrete implementations like SQLDatabaseService or NoSQLDatabaseService can be injected, making the system more flexible and easier to maintain.

 

 

Here's a C# code example for the library management system that adheres to the SOLID principles:

 

 

Single Responsibility Principle (SRP)

 

public class BookIssueService
{
    public void IssueBook(Book book, Member member)
    {
        // Logic for issuing a book
    }
}

public class BookReturnService
{
    public void ReturnBook(Book book, Member member)
    {
        // Logic for returning a book
    }
}

public class FineCalculator
{
    public decimal CalculateFine(Book book, Member member)
    {
        // Logic for calculating fine
        return 0.0m;
    }
}

public class MemberManager
{
    public void AddMember(Member member)
    {
        // Logic for adding a member
    }

    public void RemoveMember(Member member)
    {
        // Logic for removing a member
    }
}

 

 

Open/Closed Principle (OCP)

 

public interface IBook
{
    string Title { get; set; }
    string Author { get; set; }
}

public class PrintedBook : IBook
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int Pages { get; set; }
}

public class EBook : IBook
{
    public string Title { get; set; }
    public string Author { get; set; }
    public string Format { get; set; }
}

public class LibraryManager
{
    private List<IBook> books = new List<IBook>();

    public void AddBook(IBook book)
    {
        books.Add(book);
    }

    // Other library management methods
}

 

 

Liskov Substitution Principle (LSP)

 

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }

    public virtual string GetDescription()
    {
        return $"{Title} by {Author}";
    }
}

public class SpecialBook : Book
{
    public string SpecialFeature { get; set; }

    public override string GetDescription()
    {
        return $"{Title} by {Author}, featuring {SpecialFeature}";
    }
}

// Method that works with the base class
public void PrintBookDescription(Book book)
{
    Console.WriteLine(book.GetDescription());
}

// You can safely use SpecialBook where Book is expected
Book book = new SpecialBook { Title = "Special Book", Author = "Author", SpecialFeature = "Special Feature" };
PrintBookDescription(book);

 

 

Interface Segregation Principle (ISP)

 

public interface IIssueService
{
    void IssueBook(Book book, Member member);
}

public interface IReturnService
{
    void ReturnBook(Book book, Member member);
}

public interface IFineService
{
    decimal CalculateFine(Book book, Member member);
}

public class IssueService : IIssueService
{
    public void IssueBook(Book book, Member member)
    {
        // Logic for issuing a book
    }
}

public class ReturnService : IReturnService
{
    public void ReturnBook(Book book, Member member)
    {
        // Logic for returning a book
    }
}

public class FineService : IFineService
{
    public decimal CalculateFine(Book book, Member member)
    {
        // Logic for calculating fine
        return 0.0m;
    }
}

 

Dependency Inversion Principle (DIP)

 

public interface IDatabaseService
{
    void SaveBook(Book book);
    void RemoveBook(Book book);
    // Other database-related methods
}

public class SQLDatabaseService : IDatabaseService
{
    public void SaveBook(Book book)
    {
        // Logic for saving book to SQL database
    }

    public void RemoveBook(Book book)
    {
        // Logic for removing book from SQL database
    }
}

public class NoSQLDatabaseService : IDatabaseService
{
    public void SaveBook(Book book)
    {
        // Logic for saving book to NoSQL database
    }

    public void RemoveBook(Book book)
    {
        // Logic for removing book from NoSQL database
    }
}

public class LibraryManager
{
    private readonly IDatabaseService _databaseService;

    public LibraryManager(IDatabaseService databaseService)
    {
        _databaseService = databaseService;
    }

    public void AddBook(Book book)
    {
        _databaseService.SaveBook(book);
    }

    public void RemoveBook(Book book)
    {
        _databaseService.RemoveBook(book);
    }
}

 

 

By adhering to the SOLID principles, the library management system becomes more modular, easier to maintain, and flexible to future changes. Each principle addresses specific design problems and contributes to the creation of high-quality software.

 

Download our free train tracker application from the Play Store and get prized!

Card Image