God Interfaces: Anti-Pattern & Interface Segregation
This article is a definition of terms for the God Interface Anti-Pattern – including solution approaches and best practices.
In a Nutshell
God Interfaces are a design pattern in software development that provides a class that is accessible to many other classes and provides all necessary functions for calling libraries or frameworks.
Compact Technical Description
A God Interface is an anti-pattern in which an interface has too many responsibilities and methods. It violates the Interface Segregation Principle (ISP) from the SOLID principles.
Problems with God Interfaces:
- Too many methods: Interface becomes cluttered and difficult to understand
- High coupling: Implementations must implement unnecessary methods
- Poor maintainability: Changes affect many implementations
- Violation of SRP: An interface has multiple reasons to change
Solution through Interface Segregation:
- Small, focused interfaces: Each interface has a clear responsibility
- Client-specific interfaces: Implementations only need to implement relevant methods
- Better testability: Smaller interfaces are easier to mock
- Reduced coupling: Changes only affect affected implementations
Exam-Relevant Key Points
- God Interface: Interface with too many responsibilities
- Interface Segregation Principle: Clients should not be forced to implement methods they don’t use
- SOLID Principles: ISP is part of the SOLID principles
- Anti-Pattern: God Interface is a common design error
- Maintainability: Small interfaces are easier to maintain
- Coupling: God Interfaces unnecessarily increase coupling
- IHK-relevant: Important for software architecture and design
Core Components
- God Interface: An interface with too many methods/responsibilities
- Interface Segregation: Division into small, focused interfaces
- SOLID Principles: Collection of design principles
- Single Responsibility Principle: Each class should have one responsibility
- Dependency Inversion: Dependence on abstractions, not concrete implementations
- Client-Specific Interfaces: Interfaces tailored to specific requirements
- Cohesion: Strong relationship between interface elements
- Coupling: Minimization of dependencies
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);
// Permissions
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);
}
// Permissions
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;
// Only implement relevant methods
@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
- Reduced coupling: Implementations only depend on relevant interfaces
- Better testability: Smaller interfaces are easier to mock
- Clearer responsibilities: Each interface has a clear purpose
- Flexibility: Different implementations for different requirements
Disadvantages of God Interfaces
- High complexity: Too many methods make interfaces cluttered
- Strong coupling: Implementations must carry unnecessary dependencies
- Poor testability: Large interfaces are difficult to mock
- SOLID violations: Violates ISP and often SRP as well
Best Practices
1. Interface Design Guidelines
// GOOD: Interface with 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 has too many responsibilities and methods, which leads 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.
-
How does ISP differ from SRP? SRP refers to classes (one responsibility), ISP refers to interfaces (no unnecessary methods).
-
When are large interfaces acceptable? Almost never - when an interface becomes too large, it should be split up.
Most Important Sources
- https://de.wikipedia.org/wiki/Interface_Segregation_Principle
- https://refactoring.guru/design-patterns/interface-segregation
- https://www.baeldung.com/java-interface-segregation-principle