Europe: +41 78 715 83 09 - Asia: +84 ‎975 112 112
contact@finix.asia

Blog

4 Jan 2018

SOLID: Interface Segregation Principle

//
Comments0

Technologies used:   Kotlin 1.2.10 | Maven 3.3.9 | Spek 1.1.5

Interface Segregation Principle

The Interface Segregation Principle represents the “I” of the five SOLID principles of object-oriented programming to write well-designed code that are more readable, maintainable, and easier to upgrade and modify. This principle was first used by Robert C. Martin while consulting for Xerox, which he mentioned in his 2002 book, Agile Software Development: Principles, Patterns and Practices. This principle states that “Clients should not be forced to depend on methods that they do not use”. Here, the term “Clients” refers to the implementing classes of an interface.

What the Interface Segregation Principle says is that your interface should not be bloated with methods that implementing classes don’t require. For such interfaces, also called “fat interfaces”, implementing classes are unnecessarily forced to provide implementations (dummy/empty) even for those methods that they don’t need. In addition, the implementing classes are subject to change when the interface changes. An addition of a method or change to a method signature requires modifying all the implementation classes even if some of them don’t use the method.

Bad Example

package vn.finixasia.didemo.bean.vehicle

interface Vehicle {
    fun startEngine()
    fun stopEngine()
}

Our Bicycle now implement the interface Vehicle

package vn.finixasia.didemo.bean.vehicle

class Bicycle: Vehicle {
    override fun startEngine() {
        throw UnsupportedOperationException()
    }

    override fun stopEngine() {
        throw UnsupportedOperationException()
    }
}

This is a typical example of segregation violation, it is also bad for design as a developer would not understand why for that particular case the startEngine and stopEngine where not implemented.  It also violates the Open-Close principle, as for making it work we add a new function call ride because now we will need to modify each class who implemented the Vehicle interface.

Better Example

To improve all this, we will segregate the vehicle interface into 2 others interface as follow:

package vn.finixasia.didemo.bean.vehicle

interface Vehicle
package vn.finixasia.didemo.bean.vehicle

interface Engine : Vehicle {
    fun startEngine()
    fun stopEngine()
}
package vn.finixasia.didemo.bean.vehicle

interface Ride: Vehicle {
    fun start()
    fun stop()
}

And now we implement as follow

package vn.finixasia.didemo.bean.vehicle

open class DeviceWithEngine: TrasportationDevice(), Engine, Vehicle {
    override fun stopEngine() {}

    override fun startEngine() {}
}

And for the without Engine

package vn.finixasia.didemo.bean.vehicle

open class DeviceWithoutEngine: TrasportationDevice(), Vehicle, Ride {
    override fun start() {}

    override fun stop() {}
}

So, for example, the Bicycle would be implemented as following

package vn.finixasia.didemo.bean.vehicle

class Bicycle: DeviceWithoutEngine() {
    override fun start() {}
    override fun stop() {}
}

 

Leave a Reply

Translate »