God Interfaces: Anti-Pattern & Interface Segregation
This article explains the God Interface Anti-Pattern — what it is, why it’s problematic, and how to fix it.
In a Nutshell
God Interfaces are a design pattern in software development where a single interface provides access to many operations and handles all the functionality needed to interact with libraries or frameworks.
Quick Definition
A God Interface is an anti-pattern where one interface accumulates too many responsibilities and methods. It violates the Interface Segregation Principle (ISP) from the SOLID principles.
Problems with God Interfaces:
- Too many methods: The interface becomes unwieldy and hard to understand
- High coupling: Implementations must implement unnecessary methods
- Poor maintainability: Changes ripple through many implementations
- SRP violation: The interface has multiple reasons to change
Solution through Interface Segregation:
- Small, focused interfaces: Each interface has a single, clear responsibility
- Client-specific interfaces: Implementations only need to provide relevant methods
- Better testability: Smaller interfaces are easier to mock
- Lower coupling: Changes affect only the implementations that matter
Key Exam Points
- God Interface: An interface with too many responsibilities
- Interface Segregation Principle: Clients should not be forced to implement methods they don’t use
- SOLID Principles: ISP is one of the five SOLID principles
- Anti-Pattern: God Interface is a common design mistake
- Maintainability: Smaller interfaces are easier to maintain
- Coupling: God Interfaces introduce unnecessary coupling
- Exam-relevant: Critical for software architecture and design
Core Components
- God Interface: An interface with too many methods or responsibilities
- Interface Segregation: Breaking large interfaces into small, focused ones
- SOLID Principles: A collection of design principles
- Single Responsibility Principle: Each class should have one reason to change
- Dependency Inversion: Depend on abstractions, not concrete implementations
- Client-Specific Interfaces: Interfaces tailored to specific use cases
- Cohesion: Strong relationships between interface members
- Coupling: Minimizing dependencies between components
Practical Examples
God Interface (Anti-Pattern)
// BAD: God Interface with too many responsibilities
interface UserService {
// User management
User createUser(String username, String email);
void deleteUser(Long userId);
User updateUser(Long userId, User updates);
User getUserById(Long userId);
List<User> getAllUsers();
// Authentication
boolean login(String username, String password);
void logout(Long userId);
boolean changePassword(Long userId, String oldPassword, String newPassword);
// Authorization
void grantPermission(Long userId, String permission);
void revokePermission(Long userId, String permission);
boolean hasPermission(Long userId, String permission);
// Notifications
void sendEmail(Long userId, String subject, String message);
void sendSMS(Long userId, String message);
// Logging
void logUserAction(Long userId, String action);
List<LogEntry> getUserLogs(Long userId);
}
Solution through Interface Segregation
// GOOD: Small, focused interfaces
// User management
interface UserRepository {
User create(User user);
void delete(Long userId);
User update(Long userId, User updates);
User findById(Long userId);
List<User> findAll();
}
// Authentication
interface AuthenticationService {
boolean authenticate(String username, String password);
void logout(Long userId);
boolean changePassword(Long userId, String oldPassword, String newPassword);
}
// Authorization
interface AuthorizationService {
void grant(Long userId, String permission);
void revoke(Long userId, String permission);
boolean hasPermission(Long userId, String permission);
}
// Notifications
interface NotificationService {
void sendEmail(Long userId, String subject, String message);
void sendSMS(Long userId, String message);
}
// Logging
interface AuditService {
void logUserAction(Long userId, String action);
List<LogEntry> getUserLogs(Long userId);
}
// Implementation only needs relevant interfaces
class UserServiceImpl implements UserRepository, AuthenticationService {
private final UserRepository userRepo;
private final PasswordEncoder passwordEncoder;
// Implement only the methods that matter
@Override
public User create(User user) {
return userRepo.create(user);
}
@Override
public boolean authenticate(String username, String password) {
User user = userRepo.findByUsername(username);
return user != null && passwordEncoder.matches(password, user.getPassword());
}
// ... other relevant methods
}
Client-Specific Interfaces
// Different clients need different functionality
// For admin panel
interface AdminUserService {
User createUser(String username, String email);
void deleteUser(Long userId);
List<User> getAllUsers();
}
// For login system
interface LoginService {
boolean authenticate(String username, String password);
void logout(Long userId);
}
// For profile editing
interface ProfileService {
User updateProfile(Long userId, ProfileUpdates updates);
boolean changePassword(Long userId, String oldPassword, String newPassword);
}
// Each implementation is focused and testable
class AdminUserServiceImpl implements AdminUserService {
private final UserRepository userRepository;
private final AuditService auditService;
@Override
public User createUser(String username, String email) {
User user = new User(username, email);
User created = userRepository.create(user);
auditService.logUserAction(created.getId(), "USER_CREATED");
return created;
}
}
Advantages and Disadvantages
Advantages of Interface Segregation
- Better maintainability: Smaller interfaces are easier to change
- Lower coupling: Implementations depend only on what they need
- Better testability: Smaller interfaces are easier to mock
- Clear responsibilities: Each interface serves a single purpose
- Flexibility: Different implementations can serve different needs
Disadvantages of God Interfaces
- High complexity: Too many methods make interfaces hard to grasp
- Tight coupling: Implementations carry unnecessary dependencies
- Poor testability: Large interfaces are difficult to mock
- SOLID violations: Breaks ISP and often violates SRP
Best Practices
1. Interface Design Guidelines
// GOOD: Interface with a clear purpose
interface EmailValidator {
boolean isValid(String email);
String normalize(String email);
}
// BAD: Interface with multiple purposes
interface ValidationService {
boolean isValidEmail(String email);
boolean isValidPhone(String phone);
boolean isValidAddress(Address address);
String normalizeEmail(String email);
String normalizePhone(String phone);
}
2. Role-Based Interfaces
// Role-based interfaces
interface Reader {
String read();
}
interface Writer {
void write(String content);
}
interface ReaderWriter extends Reader, Writer {
// Combines both roles
}
3. Marker Interfaces
// Marker interfaces for type safety
interface Serializable { }
interface Cloneable { }
interface Remote { }
Common Exam Questions
-
What is a God Interface and why is it problematic? A God Interface accumulates too many responsibilities and methods, leading to high coupling and poor maintainability.
-
Explain the Interface Segregation Principle! Clients should not be forced to implement methods they don’t use. Interfaces should be small and focused on a single purpose.
-
How does ISP differ from SRP? SRP applies to classes (one reason to change), while ISP applies to interfaces (no unnecessary methods).
-
When are large interfaces acceptable? Rarely, if ever. When an interface grows too large, it should be broken into smaller pieces.
Key Resources
- https://en.wikipedia.org/wiki/Interface_segregation_principle
- https://refactoring.guru/design-patterns/interface-segregation
- https://www.baeldung.com/java-interface-segregation-principle



