Interface Segregation Principle (ISP)

Intent

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

Description

This principle deals with non-cohesive interfaces (interfaces that contain methods that are not used by all the clients of the interface). This leads to interface pollution and such interface is called as a fat interface. The clients are forced to depend on the methods they are never going to use and might lead to runtime errors or crashes.

Consider an interface IFile used for file operations. Two classes have been inherited from it; TextFile and SocketFile. The code is shown below:

IFile.cs

interface IFile
{
void open();
void close();
void read();
void write();
void seek();
void position();
}

TextFile.cs

class TextFile : IFile
{
public void open()
{
//implementation
}

public void close()
{
//implementation
}

public void read()
{
//implementation
}

public void write()
{
//implementation
}

public void seek()
{
//implementation
}

public void position()
{
//implementation
}
}

SocketFile.cs

class SocketFile : IFile
{
public void open()
{
//implementation
}

public void close()
{
//implementation
}

public void read()
{
//implementation
}

public void write()
{
//implementation
}

public void seek()
{
//cannot seek in a socket
throw new NotImplementedException();
}

public void position()
{
//cannot get the position in a socket
throw new NotImplementedException();
}
}

The IFile interface contains certain methods which are not useful for the clients who use SocketFile class. The methods seek() and position() cannot be implemented in SocketFile, therefore they throw a NotImplementedException(). Hardly a proper solution, because the client sees the interface as a contract and all the classes implementing IFile have to honor the contract. Throwing an exception for some methods means that the contract is not being honored. Thus, the IFile interface is non-cohesive is called a fat interface.

Fat interfaces violate the Liskov Substitution Principle because the derived class objects cannot be used due to unimplemented methods of the interface. We will never know when the code may throw exceptions.

Refactored Solution

The Interface Segregation Principle suggests that fat interfaces may be broken into smaller interfaces so that each interface will serve its own set of clients. It will lead to a lot more reduced coupling between the client and the server classes.

By applying Interface Segregation Principle, the IFile interface can be broken into two interfaces as shown:

IFile.cs

interface IFile
{
void open();
void close();
void read();
void write();
}

IDiskFile.cs

interface IDiskFile : IFile
{
void seek();
void position();
}

IDiskFile interface will be implemented by the TextFile class which will implement all the methods of both the interfaces. SocketFile will implement only IFile interface and does not have to worry about unrelated methods such as seek() and position().You can see Dependency Inversion Principle (DIP) as the next post. Stay tuned with us.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s