BlackWaspTM
Programming Concepts

Interface Segregation Principle

The fifth article in the SOLID Principles series describes the Interface Segregation Principle (ISP). The ISP specifies that clients should not be forced to depend upon interfaces that they do not use. Instead, those interfaces should be minimised.

The Principle

Some classes have public interfaces that are not cohesive. They may include several groups of members where each group is used by a different set of client classes. The groups may be entirely separate or there may be overlap between the members used by different clients. Ideally all classes would have cohesive interfaces. Unfortunately, this is not always possible.

The Interface Segregation Principle (ISP) states that clients should not be forced to depend upon interfaces that they do not use. When we have non-cohesive interfaces, the ISP guides us to create multiple, smaller, cohesive interfaces. The original class implements each such interface. Client code can then refer to the class using the smaller interface without knowing that other members exist.

When you apply the ISP, class and their dependencies communicate using tightly-focussed interfaces, minimising dependencies on unused members and reducing coupling accordingly. Smaller interfaces are easier to implement, improving flexibility and the possibility of reuse. As fewer classes share interfaces, the number of changes that are required in response to an interface modification is lowered. This increases robustness.

Example Code

To demonstrate the application of the ISP, we can review some code that violates it and explain how to refactor to comply with the principle. The following code shows the outline of three classes:

public class Contact
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string EmailAddress { get; set; }
    public string Telephone { get; set; }
}

    
public class Emailer
{
    public void SendMessage(Contact contact, string subject, string body)
    {
        // Code to send email, using contact's email address and name
    }
}

    
public class Dialler
{
    public void MakeCall(Contact contact)
    {
        // Code to dial telephone number of contact
    }
}

The Contact class represents a person or business that can be contacted. The class holds the person's name, address, email address and telephone number. The Emailer class sends email messages to contacts. The contact and the subject and body of the email are passed to the parameters. The Dialler class extracts the telephone number from the Contact and calls it using an automatic dialling system.

The example code violates the ISP. The Emailer class is a client of the Contact class. Although it only requires access to the Name and EmailAddress properties, it is aware of other members too. Similarly, the Dialler class uses a single property, "Telephone". However, it has access to the entire Contact interface.

20 January 2011