Tutorialsteacher

Follow Us

Articles
  • C#
  • C# OOP
  • ASP.NET Core
  • ASP.NET MVC
  • LINQ
  • Inversion of Control (IoC)
  • Web API
  • JavaScript
  • TypeScript
  • jQuery
  • Angular 11
  • Node.js
  • D3.js
  • Sass
  • Python
  • Go lang
  • HTTPS (SSL)
  • Regex
  • SQL
  • SQL Server
  • PostgreSQL
  • MongoDB
  • C# - Get Started
  • C# - Version History
  • C# - First Program
  • C# - Keywords
  • C# - Class and Objects
  • C# - Namespace
  • C# - Variables
  • C# - Implicitly-Typed Variables
  • C# - Data Types
  • Numbers
  • Strings
  • DateTime
  • Structure
  • Enum
  • StringBuilder
  • Anonymous Types
  • Dynamic Types
  • Nullable Types
  • C# - Value & Reference Types
  • C# - Interface
  • C# - Operators
  • C# - if else Statements
  • C# - Ternary Operator ?:
  • C# - Switch
  • C# - For Loop
  • C# - While Loop
  • C# - Do-while Loop
  • C# - Partial Class
  • C# - Static
  • C# - Array
  • Multidimensional Array
  • Jagged Array
  • C# - Indexer
  • C# - Generics
  • Generic Constraints
  • C# - Collections
  • ArrayList
  • List
  • SortedList
  • Dictionary
  • Hashtable
  • Stack
  • Queue
  • C# - Tuple
  • C# - ValueTuple
  • C# - Built-in Exceptions
  • Exception Handling
  • throw
  • Custom Exception
  • C# - Delegates
  • Func Delegate
  • Action Delegate
  • Predicate Delegate
  • Anonymous Methods
  • C# - Events
  • C# - Covariance
  • C# - Extension Method
  • C# - Stream I/O
  • C# - File
  • C# - FileInfo
  • C# - Object Initializer
  • OOP - Overview
  • Object-Oriented Programming
  • Abstraction
  • Encapsulation
  • Association & Composition
  • Inheritance
  • Polymorphism
  • Method Overriding
  • Method Hiding
  • C# - Solid Principles
  • Single Responsibility Principle
  • Open/Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle
  • Design Patterns
  • Singleton
  • Abstract Factory
  • Factory Method
Entity Framework Extensions - Boost EF Core 9
  Bulk Insert
  Bulk Delete
  Bulk Update
  Bulk Merge

SOLID: Interface Segregation Principle

Interface Segregation Principle (ISP) is the fourth principle of SOLID principles. It can be used in conjunction with LSP.

Interface Segregation Principle (ISP) states that:

Clients should not be forced to depend on methods they do not use.

Now, you may wondering, who is the client and what and whose methods it is talking about?

Here, a client is a code that calls the methods of a class with an instance of the interface. For example, a class implements an interface that contains 10 methods. Now, you create an object of that class with a variable of that interface and call only 5 methods for the functionality you wanted and never call the other 5 methods. So, this means that the interface contains more methods that are not used by all client codes. It is called a fat interface. ISP suggests segregating that interface into two or more interfaces so that a class can implement the specific interface that it requires.

Let's use the following interface to learn ISP in detail:

Example: Fat Interface
public interface IStudentRepository
{
    void AddStudent(Student std);
    void EditStudent(Student std);
    void DeleteStudent(Student std);

    void AddCourse(Course cs);
    void EditCourse(Course cs);
    void DeleteCourse(Course cs);

    bool SubscribeCourse(Course cs);
    bool UnSubscribeCourse(Course cs);
    IList<Student> GetAllStudents();
    IList<Student> GetAllStudents(Course cs);

    IList<Course> GetAllCourse();
    IList<Course> GetAllCourses(Student std);
}

public class StudentRepository : IStudentRepository
{
    public void AddCourse(Course cs)
    {
        //implementation code removed for better clarity
    }

    public void AddStudent(Student std)
    {
        //implementation code removed for better clarity
    }

    public void DeleteCourse(Course cs)
    {
        //implementation code removed for better clarity
    }

    public void DeleteStudent(Student std)
    {
        //implementation code removed for better clarity
    }

    public void EditCourse(Course cs)
    {
        //implementation code removed for better clarity
    }

    public void EditStudent(Student std)
    {
        //implementation code removed for better clarity
    }

    public IList<Course> GetAllCourse()
    {
        //implementation code removed for better clarity
    }

    public IList<Course> GetAllCourses(Student std)
    {
        //implementation code removed for better clarity
    }

    public IList<Student> GetAllStudents()
    {
        //implementation code removed for better clarity
    }

    public IList<Student> GetAllStudents(Course cs)
    {
        //implementation code removed for better clarity
    }

    public bool SubscribeCourse(Course cs)
    {
        //implementation code removed for better clarity
    }

    public bool UnSubscribeCourse(Course cs)
    {
        //implementation code removed for better clarity
    }
}

The above IStudentRepository interface contains 12 methods for different purposes. The StudentRepository class implements the IStudentRepository interface.

Now, after some time, you observe that not all instances of the StudentRepository class call all the methods. Sometimes it calls methods that perform student-related tasks or sometimes calls course-related methods. Also, the StudentRepository does not follow the single responsibility principle because you may need to edit its code if student related as well as course-related business logic changes.

To apply ISP to the above problem, we can split our large interface IStudentRepository and create another interface ICourseRepository with all course-related methods, as shown below.

Example: Interfaces after apllying ISP
public interface IStudentRepository
{
    void AddStudent(Student std);
    void EditStudent(Student std);
    void DeleteStudent(Student std);

    bool SubscribeCourse(Course cs);
    bool UnSubscribeCourse(Course cs);
    IList<Student> GetAllStudents();
    IList<Student> GetAllStudents(Course cs);
}

public interface ICourseRepository
{
    void AddCourse(Course cs);
    void EditCourse(Course cs);
    void DeleteCourse(Course cs);

    IList<Course> GetAllCourse();
    IList<Course> GetAllCourses(Student std);
}

Now, we can create two concrete classes that implement the above two interfaces. This will automatically support SRP and increase cohesion.

ISP is not specific to interfaces only but it can be used with abstract classes or any class that provides some services to the client code.

ISP helps in implementing Liskov Substitution Principle, increasing cohesion that in turn supports the Single Responsibility Principle.

The following code smells detects ISP violation:

  1. When you have large interfaces.
  2. When you implement an interface in a concrete class where some methods do not have any implementation code or throw NotImplementedException.
  3. When you call only a small set of methods of a larger interface.

The solution to ISP violations:

  1. Split large interfaces into smaller ones.
  2. inherit multiple small interfaces if required.
  3. Use the adapter design pattern for the third-party large interface so that your code can work with the adapter.
TUTORIALSTEACHER.COM

TutorialsTeacher.com is your authoritative source for comprehensive technologies tutorials, tailored to guide you through mastering various web and other technologies through a step-by-step approach.

Our content helps you to learn technologies easily and quickly for learners of all levels. By accessing this platform, you acknowledge that you have reviewed and consented to abide by our Terms of Use and Privacy Policy, designed to safeguard your experience and privacy rights.

[email protected]

ABOUT USTERMS OF USEPRIVACY POLICY
copywrite-symbol

2024 TutorialsTeacher.com. (v 1.2) All Rights Reserved.