Добро пожаловать в мир принципов SOLID – секретный рецепт написания кода, который делает код не просто функциональным, но масштабируемым и простым в обслуживании. В этом путешествии мы рассмотрим, как эти принципы становятся нашим компасом в кодировании, направляя к созданию хорошего ПО.
Давайте рассмотрим каждый из принципов SOLID на примерах Java.
Давайте рассмотрим каждый из принципов SOLID на примерах Java.
Single Responsibility Principle - принцип единой ответственности
Идея: у класса должна быть только одна причина для изменения, то есть у него должна быть только одна работа или ответственность
Пример: представьте себе шеф-повара в ресторане. Он готовит еду. Он не занимается бронированием столиков и не убирают за ними.
public class UserService {
public void registerUser(User user) {
}
public void deleteUser(User user) {
}
}
Класс UserService обрабатывает действия, связанные с пользователем, уделяя особое внимание регистрации и удалению пользователей. Он не участвует в задачах, выходящих за рамки его обязанностей, ориентированных на пользователя.
Open/Closed Principle - принцип открытости/закрытости
Идея: объекты должны быть открыты для расширения, но закрыты для модификации.
Пример: представьте магазин, который продает одежду. Вы можете добавлять новые предметы одежды, не меняя структуру магазина.
Пример: представьте магазин, который продает одежду. Вы можете добавлять новые предметы одежды, не меняя структуру магазина.
public interface Shape {
double calculateArea();
}
public class Circle implements Shape {
private double radius;
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
public class Square implements Shape {
private double side;
@Override
public double calculateArea() {
return side * side;
}
}
Интерфейсы, такие как Shape, остаются открытыми для добавления новых фигур (расширений) без изменения существующих фигур (закрыты для модификации).
Прицип подстановки Лисков
Идея: подтипы должны быть взаимозаменяемы со своими базовыми типами без изменения корректности программы.
Пример: если программа работает с рыбой, она должна работать с любым подтипом рыбы, таким как форель.
Пример: если программа работает с рыбой, она должна работать с любым подтипом рыбы, таким как форель.
public class Fish {
public void swim() {
}
}
public class Trout extends Fish {
}
Trout - это подтип рыбы, и его можно использовать взаимозаменяемо с базовым типом (Fish).
Interface Segregation Principle - принцип разделения интерфейсов
Идея: ни один класс не должен реализовывать интерфейс, который он не использует.
Пример: подумайте о смартфоне. Ему не нужно реализовывать функции, которые он не поддерживает, такие как печать.
Пример: подумайте о смартфоне. Ему не нужно реализовывать функции, которые он не поддерживает, такие как печать.
// Вместо единого монолитного интерфейса
public interface Worker {
void work();
void eat();
void sleep();
}
// Отдельные интерфейсы для разных ролей
public interface Workable {
void work();
}
public interface Eatable {
void eat();
}
public interface Sleepable {
void sleep();
}
public class Employee implements Workable, Eatable {
}
В примере вместо монолитного интерфейса Worker - отдельные интерфейсы (Workable, Eatable, Sleepable) позволяют классам реализовывать только то, что им нужно (на примере класса Employee)
Dependency Inversion Principle (DIP) - принцип инверсии зависимостей
Идея: модули высокого уровня не должны зависеть от модулей низкого уровня. Все должны зависеть от абстракций.
Пример: рассмотрим пульт дистанционного управления. Ему не нужно знать внутренние детали устройств, которыми он управляет.
Пример: рассмотрим пульт дистанционного управления. Ему не нужно знать внутренние детали устройств, которыми он управляет.
// высокоуровневый модуль
public interface MessageService {
void sendMessage(String message);
}
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
}
}
public class Notification {
private final MessageService messageService;
public Notification(MessageService messageService) {
this.messageService = messageService;
}
public void sendNotification(String message) {
messageService.sendMessage(message);
}
}
В примере Notification зависит от абстракции (MessageService), допускающей различные реализации (например, EmailService) без изменения модуля высокого уровня.
Заключение
Освоить принципы SOLID - все равно что получить секретный рецепт для написания крутого кода. Применение этих надежных принципов в процессе разработки гарантирует, что ваше ПО будет не только функциональным, но и масштабируемым, поддерживаемым и адаптируемым к будущим изменениям.