Какие знаешь принципы чистого кода?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Принципы чистого кода
Чистый код — это код, который легко читать, понимать и модифицировать. Это основа профессиональной разработки. Расскажу о ключевых принципах, которые использую в ежедневной работе.
1. Значащие имена
Имена переменных, методов и классов должны отражать их назначение. Избегаю аббревиатур и просмотра исходного кода для понимания.
// ❌ Плохо
int d; // количество дней
List<int[]> l; // список значений
public void handle(Object o) {}
// ✅ Хорошо
int daysSinceCreation;
List<int[]> userActivityValues;
public void processUserAuthentication(User user) {}
2. Функции должны быть маленькими
Метод должен делать одну вещь и делать её хорошо. Идеальная длина — 5-10 строк.
// ❌ Плохо
public void processOrder(Order order) {
validateOrder(order);
calculateTax(order);
calculateShipping(order);
applyDiscounts(order);
saveOrder(order);
sendEmail(order);
logActivity(order);
// ... ещё 20 строк
}
// ✅ Хорошо
public void processOrder(Order order) {
validateOrder(order);
enrichOrderWithCalculations(order);
persistOrder(order);
}
3. Один уровень абстракции на метод
Один метод не должен смешивать высокоуровневые операции с низкоуровневыми деталями.
// ❌ Плохо
public void generateReport() {
// Высокоуровневая логика
List<User> users = getUsersFromDatabase();
// Низкоуровневые детали
Class.forName("org.postgresql.Driver");
Statement stmt = connection.createStatement();
// ...
}
// ✅ Хорошо
public void generateReport() {
List<User> users = userRepository.findAll();
reportGenerator.generate(users);
}
4. Обработка ошибок
Ошибки должны обрабатываться правильно и не замалчиваться.
// ❌ Плохо
try {
// код
} catch (Exception e) {
e.printStackTrace(); // это не обработка
}
// ✅ Хорошо
try {
// код
} catch (FileNotFoundException e) {
logger.error("File not found: {}", fileName, e);
throw new ApplicationException("Unable to load configuration", e);
} catch (IOException e) {
logger.warn("IO error occurred", e);
retryOperation();
}
5. DRY (Don't Repeat Yourself)
Избегаю дублирования кода. Общая логика должна быть в отдельных методах.
// ❌ Плохо
public decimal calculatePrice() {
decimal price = basePrice * 100;
price = price - (price * discount / 100);
return price;
}
public decimal calculateShipping() {
decimal shipping = baseShipping * 100;
shipping = shipping - (shipping * discount / 100);
return shipping;
}
// ✅ Хорошо
private decimal applyDiscount(decimal amount) {
return amount - (amount * discount / 100);
}
public decimal calculatePrice() {
return applyDiscount(basePrice * 100);
}
public decimal calculateShipping() {
return applyDiscount(baseShipping * 100);
}
6. Комментарии
Код должен быть самодокументирующимся. Комментарии нужны только для почему, а не для что.
// ❌ Плохо
// Итерируем по списку пользователей
for (User user : users) {
// Проверяем, активен ли пользователь
if (user.isActive()) {
// Отправляем email
sendEmail(user);
}
}
// ✅ Хорошо
for (User activeUser : users) {
if (activeUser.isActive()) {
sendEmail(activeUser);
}
}
// Комментарий объясняет нетривиальное решение
// Используем LinkedList вместо ArrayList потому что преобладают операции удаления
List<Task> taskQueue = new LinkedList<>();
7. Форматирование
Код должен быть красиво отформатирован для лучшей читаемости.
- Последовательный отступ (4 пробела или 1 таб)
- Одна пустая строка между методами
- Максимум 120 символов на строку
- Группировка связанного кода
8. SOLID принципы
S — Single Responsibility: каждый класс отвечает за одно O — Open/Closed: открыт для расширения, закрыт для модификации L — Liskov Substitution: подклассы заменяемы на родителей I — Interface Segregation: много специфичных интерфейсов лучше одного общего D — Dependency Inversion: зависи от абстракций, не от конкретики
9. Тестируемость
Код должен быть легко тестируемым. Это естественное следствие чистого кода.
// ❌ Плохо — сложно тестировать
public class OrderProcessor {
public void processOrder() {
Connection conn = DriverManager.getConnection("jdbc:...");
// hardcoded зависимости
}
}
// ✅ Хорошо — инъекция зависимостей
public class OrderProcessor {
private final OrderRepository repository;
private final PaymentService payment;
public OrderProcessor(OrderRepository repo, PaymentService payment) {
this.repository = repo;
this.payment = payment;
}
}
10. Минимализм
Не добавляй код "на будущее". YAGNI — You Aren't Gonna Need It. Это избегает сложности и облегчает поддержку.
Заключение
Чистый код — это постоянная практика и привычка. Это требует дополнительного времени на написание, но экономит недели на поддержку и модификацию. Начинаю рефакторить код после написания, и это стало частью моего workflow'а.