Ответ
Это принцип инверсии зависимостей (D — Dependency Inversion Principle, часть SOLID). Код верхнего уровня не должен зависеть от деталей нижнего уровня, оба должны зависеть от абстракций (интерфейсов или абстрактных классов). Это повышает гибкость, тестируемость и упрощает замену компонентов.
Пример: Сервис уведомлений.
- Определяем абстракцию (интерфейс):
// Абстракция interface MessageSender { void send(String recipient, String message); } - Создаём конкретные реализации:
// Конкретная реализация 1 class EmailSender implements MessageSender { @Override public void send(String recipient, String message) { // Логика отправки email System.out.println("Email to " + recipient + ": " + message); } }
// Конкретная реализация 2 class SmsSender implements MessageSender { @Override public void send(String recipient, String message) { // Логика отправки SMS System.out.println("SMS to " + recipient + ": " + message); } }
3. **Класс высокого уровня зависит от абстракции:**
```java
class NotificationService {
// Зависимость от интерфейса, а не от EmailSender или SmsSender
private final MessageSender sender;
// Внедрение зависимости через конструктор (Dependency Injection)
public NotificationService(MessageSender sender) {
this.sender = sender;
}
public void notifyUser(String user, String msg) {
sender.send(user, msg);
}
}
- Использование:
public class Main { public static void main(String[] args) { // Легко меняем реализацию, не трогая NotificationService MessageSender sender = new EmailSender(); // или new SmsSender() NotificationService service = new NotificationService(sender); service.notifyUser("user@example.com", "Your order is ready!"); } }Ключевые преимущества:
- Гибкость:
NotificationServiceне знает о деталях отправки. - Тестируемость: Можно подменить
MessageSendermock-объектом в unit-тестах. - Расширяемость: Добавление нового способа отправки (например,
PushNotificationSender) не требует изменений вNotificationService.
- Гибкость: