Back to blog
DevelopmentSeptember 14, 2011

Decoupling Classes with Interfaces in OOP

A practical guide to using interfaces for decoupling tightly bound classes, illustrated with an Android development example.


While building a Login module for an Android application, I encountered a common coupling problem. The Login class needed to call three methods on the calling Activity, which created a direct dependency between the two.


The Problem


The Login class was tightly coupled to a specific Activity. Reusing it from a different Activity would require modifying the Login class itself, violating the Open/Closed Principle.


The Solution: Define an Interface


By introducing an interface, we establish a contract that any caller must fulfill:


public interface LoginCallback {

void onLoginSuccess(User user);

void onLoginFailed(String error);

void onLoginProgress(int percent);

}


Now the Login class depends only on the interface, not on any concrete Activity:


public class LoginManager {

private LoginCallback callback;


public LoginManager(LoginCallback callback) {

this.callback = callback;

}


public void login(String username, String password) {

// perform login

callback.onLoginSuccess(user);

}

}


Any Activity that implements LoginCallback can use LoginManager without modification. The class is now reusable, testable, and decoupled from its consumers. This is a core principle of good object-oriented design.