top of page
Writer's pictureJennifer Eve Vega

SOLID: Interface Segregation Principle

Updated: Aug 1, 2023

Simply put, this means, a client should not depend on something it doesn't need.


Ways to identify if you're violating Interface Segregation Principle:

- Too many functions in an interface

- Empty implementation, or simply throwing exceptions

- A class is implementing methods that are not needed


If a client only needs part of the interface, it still ends up depending on everything. Here's an example:


Let's say, you have an interactor that will let you know what screen you should show to the user. You will show the Home screen if user is already logged in, if not, you will show an Onboarding screen of you app.


Here's a simple diagram:

We have an InitialScreenInteractor depending on UserRepositoryProtocol (or Interface). And our UserRepository which implements UserRepositoryProtocol depends on UserDao (DAO - Data Access Object) and UserService (API).


In this example, the interactor only needs to know if there's a user. But given this setup, the InitialScreenInteractor ended up depending on everything - it is indirectly depending on UserDao and UserService, too. Even though it doesn't need the UserService.


Now, if we are going to test our interactor, we will be forced to implement the other two methods (saveUser and uploadAvatar) that we don't really needed.

class InitialScreenInteractorTests: XCTestCase {
    private var sut: InitialScreenInteractor
    
    override func setUpWithError() throws {
        let repoMock = UserRepositoryMock()
        sut = InitialScreenInteractor(userRepo: repoMock)
    }
    
    private class UserRepositoryMock: UserRepositoryProtocol {
        func getUser() -> User? {
            return User()
        }
        
        // Not Needed
        func saveUser() -> Completable
        func uploadAvatar(image: Data) -> Completable
    }
}

With Interface Segregation Principle, we'll gonna have to create a different interface for getting the user.





Now, if we're going to test our interactor, we no longer need to implement methods we don't need.

class InitialScreenInteractorTests: XCTestCase {
    private var sut: InitialScreenInteractor
    
    override func setUpWithError() throws {
        let repoMock = GetUserRepositoryMock()
        sut = InitialScreenInteractor(userRepo: repoMock)
    }
    
    private class GetUserRepositoryMock: GetUserRepositoryProtocol {
        func getUser() -> User? {
            return User()
        }
    }
}


Recent Posts

See All

Comments


bottom of page