Implementing the interface segregation principle

Refactor fat interfaces and create functionally separate interfaces to ensure that clients are not forced to implement interfaces that don't need or use

Interface Segregation Principle

Interface Segregation Principle

The interface segregation principle is one of the SOLID principles that states that the clients should not be compelled to implement an interface that contains declarations of members or operations that they would not need or never use. Such interfaces are known as "fat" or polluted interfaces (also called interface bloat) as they contain too many operations.

Rather than having a fat interface and have the clients consume them, it is a recommended practice to break the fat interface to one or more specific and cohesive interfaces. If your code violates the interface segregation principle, you can fix it by taking advantage of the Adapter design pattern.

Image a situation in which the type that implements the interface needs to use only a few methods of the interface but not all. So, implementing such an interface where not all of the methods are relevant to the type implementing the interface is not a good practice.

So, then what's the solution or alternative? Well, you can break this fat interface into one or more interfaces if you have access to the interface source code. If it is that you have no access to the interface, all you can do is use the relevant methods and just ignore the other ones. You can just throw and instance of the NotImplementedException class from those methods of the interface you don't need at all. Note that when you are implementing an interface in a class, you must implement all of its members - otherwise the compiler would flag an error.

Let’s understand the interface segregation principle with an example. Consider three types -- the ILog interface and the FileLogger and DBLogger classes that implement the ILog interface.

  public interface ILog

    { 

        void Log(string message);

        void OpenConnection();

        void CloseConnection();

    }

The ILog interface contains the declaration of the Log method that logs a text to a file or a database. It also contains two other methods -- the OpenConnection and the CloseConnection methods. Note that these methods are used to open and close database connections while logging data to a database. These methods are not needed when you need to log data in a file. The FileLogger class implements the ILog interface and defines the Log method.

    public class FileLogger : ILog

    {

        public void Log(string message)

        {

            //Code to log to a file           

        }

    }

The DBLogger class implements the ILog interface and implements all of the methods of the ILog interface.

    public class DBLogger : ILog

    {

        public void Log(string message)

        {

            //Code to log data to a database

        }

        public void OpenConnection()

        {

            //Opens database connection

        }

        public void CloseConnection()

        {

           //Closes the database connection

        }

    }

When you compile the code, you'll see that the compiler flags errors stating that the FileLogger class doesn't implement the interface members ILog.OpenConnection() and ILog.OpenConnection(). To fix this, you are constrained to implement the ILog.OpenConnection() and ILog.CloseConnection() methods in the FileLogger class even if you would never need them. To fix this, you need to implement all of the methods of the ILog interface in the FileLogger class and throw an instance of NotImplementedException for those methods you would need at all. The modified version of the FileLogger class looks like this.

public class FileLogger : ILog

    {

        public void Log(string message)

        {

             //Code to log to a file           

        }

        public void CloseConnection()

        {

            throw new NotImplementedException();

        }

        public void OpenConnection()

        {

            throw new NotImplementedException();

        }

    }

Here is how you can segregate the interfaces and ensure that the Interface Segregation principle is adhered to.

   public interface ILog

    {

        void Log(string message);

    }

    public interface IDBLog: ILog

    {

        void OpenConnection();

        void CloseConnection();

    }

    public interface IFileLog: ILog

    {

        void CheckFileSize();

        void GenerateFileName();

    }

Note that two new interfaces have been introduced -- IDBLog and IFileLog. I've also introduced two new methods in the IFileLog interface -- these are specific to file logging operations. While the CheckFileSize method would be used to check the size of the log file -- this would be handy in case you would like to restrict the file size to a pre-defined limit and then rollover the file. The GenerateFileName method would be used to generate the new name for the log file if the current log file size has reached the maximum file size threshold.

The following code listing shows how the modified versions of the FileLogger and the DBLogger classes look like.

    public class FileLogger : IFileLog

    {

        public void CheckFileSize()

        {

            //Code to check log file size

        }

        public void GenerateFileName()

        {

            //Code to generate a new file name

        }

        public void Log(string message)

        {

            //Code to log data to the log file

        }

    }

    public class DBLogger : IDBLog

    {

        public void Log(string message)

        {

            //Code to log data to the database

        }

        public void OpenConnection()

        {

            //Code to open database connection

        }

         public void CloseConnection()

        {

            //Code to close database connection

        }

    }

This article is published as part of the IDG Contributor Network. Want to Join?

From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.