Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Чистый код
Чистый код (Clean Code) — это код, который легко читать, понимать, поддерживать и расширять. Концепция развита Робертом Мартином (Uncle Bob) и является основой профессиональной разработки. Чистый код отражает глубокое понимание проблемы и демонстрирует уважение к коллегам, которые будут работать с кодом.
Основные принципы чистого кода
1. Понятные имена
Имена переменных, функций и классов должны быть самоописывающимися:
// Плохо — непонятные имена
public class DtaProc {
public int d;
public int calc(int x, int y, int z) {
int tmp = 0;
for (int i = 0; i < x; i++) {
tmp += y * z;
}
return tmp;
}
}
// Хорошо — понятные, выразительные имена
public class DataProcessor {
private int dataCount;
public int calculateTotal(int quantity, int unitPrice, int discountPercent) {
int total = 0;
for (int item = 0; item < quantity; item++) {
total += unitPrice * (100 - discountPercent) / 100;
}
return total;
}
}
Правила для имён:
- Используй существительные для переменных и классов
- Используй глаголы для методов
- Избегай однобуквенных имён кроме счётчиков циклов
- Используй произносимые имена
- Избегай кодирования типов
2. Функции должны быть малыми
Одна функция — одна задача:
// Плохо — функция делает слишком много
public void processUserData(User user) {
if (user.getEmail() == null) {
throw new IllegalArgumentException("Email required");
}
if (user.getAge() < 18) {
throw new IllegalArgumentException("Age must be 18+");
}
database.save(user);
emailService.send(user.getEmail(), "Welcome!");
logger.info("User: " + user.getEmail());
}
// Хорошо — разделена на отдельные функции
public void processUserData(User user) {
validateUser(user);
saveUser(user);
sendWelcomeEmail(user);
logUserProcessing(user);
}
private void validateUser(User user) {
if (user.getEmail() == null) {
throw new IllegalArgumentException("Email required");
}
if (user.getAge() < 18) {
throw new IllegalArgumentException("Age must be 18+");
}
}
3. Функции должны иметь мало параметров
// Плохо — много параметров
public void createOrder(String name, String email, String phone,
String item, int qty, double price) {}
// Хорошо — используй объекты параметров
public void createOrder(OrderRequest request) {
Customer customer = request.getCustomer();
OrderItem item = request.getItem();
}
4. DRY (Don't Repeat Yourself)
Не повторяй код — выноси в функции:
// Плохо — дублирование
public void generatePDFReport() {
validateReport();
// PDF код
}
public void generateExcelReport() {
validateReport();
// Excel код
}
// Хорошо — выношу валидацию
private void validateReport() {
if (data == null) throw new IllegalStateException("Data missing");
}
5. KISS (Keep It Simple)
Пишите просто и понятно:
// Плохо — излишняя сложность
public boolean isEligible(User user) {
return user != null && user.getAge() >= 18 &&
user.getAge() <= 100 && isValidEmail(user.getEmail()) &&
(user.getStatus().equals("ACTIVE") ||
user.getStatus().equals("PENDING"));
}
// Хорошо — разбираю на части
public boolean isEligible(User user) {
return user != null && isValidAge(user.getAge()) &&
isValidEmail(user.getEmail()) && hasValidStatus(user.getStatus());
}
6. Обработка ошибок
Используй проверяемые исключения:
// Плохо — игнорирование ошибок
try {
database.connect();
} catch (SQLException e) {
e.printStackTrace();
}
// Хорошо — специфичные исключения
public void readFile(String path) throws FileNotFoundException, IOException {
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException("File: " + path);
}
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
processLine(line);
}
} catch (IOException e) {
logger.error("Error reading: " + path, e);
throw e;
}
}
7. Комментарии
Хороший код не нуждается в комментариях:
// Плохо — плохой код с комментариями
public int calc(int[] arr) {
int s = 0;
for (int i = 0; i < arr.length; i++) {
s += arr[i];
}
return s;
}
// Хорошо — понятный код
public int sumArrayElements(int[] numbers) {
int sum = 0;
for (int number : numbers) {
sum += number;
}
return sum;
}
// Лучше — Stream API
public int sumArrayElements(int[] numbers) {
return Arrays.stream(numbers).sum();
}
Комментарии уместны для:
- Объяснения сложного алгоритма
- JavaDoc для публичного API
- TODO и FIXME
8. Форматирование и стиль
// Плохо — грязное форматирование
public class BadCode{public void m(){int x=5;int y=10;}}
// Хорошо — чистое форматирование
public class CleanCode {
public void method() {
int x = 5;
int y = 10;
}
}
Правила:
- 4 пробела для отступов
- Max 120 символов в строке
- Открывающая скобка на той же строке
- Пустая строка между методами
- Логичное группирование кода
Принципы SOLID
Связаны с чистым кодом:
S — Single Responsibility — один класс, одна ответственность
// Плохо
public class UserManager {
public void registerUser(User user) {}
public void sendEmail(String email) {}
public void logActivity(String activity) {}
}
// Хорошо
public class UserService {
private UserValidator validator;
private UserRepository repository;
private NotificationService notificationService;
public void registerUser(User user) {
validator.validate(user);
repository.save(user);
notificationService.sendWelcomeEmail(user);
}
}
Контрольный список
- Понятны ли имена переменных, функций, классов?
- Функции маленькие и делают одно?
- Функции имеют не более 3 параметров?
- Нет ли дублирования кода?
- Ошибки обрабатываются правильно?
- Код отформатирован, легко читается?
- Комментарии необходимы и актуальны?
- Код протестирован (coverage 80%+)?
- Применены принципы SOLID?
- Нет ли неиспользуемого кода?
Практический пример: Рефакторинг
// Грязный код
public class OrderProcessor {
public boolean prc(Order o) {
if (o == null) return false;
if (o.getItems().isEmpty()) return false;
double total = 0;
for (int i = 0; i < o.getItems().size(); i++) {
OrderItem item = o.getItems().get(i);
total += item.getPrice() * item.getQty();
}
if (total > 5000) {
o.setDisc(0.1);
} else if (total > 1000) {
o.setDisc(0.05);
}
o.setTotal(total);
System.out.println("Order processed");
return true;
}
}
// Чистый код
public class OrderProcessor {
private final OrderRepository repository;
private final DiscountCalculator discountCalculator;
public OrderProcessor(OrderRepository repository,
DiscountCalculator discountCalculator) {
this.repository = repository;
this.discountCalculator = discountCalculator;
}
public void process(Order order) throws InvalidOrderException {
validateOrder(order);
double subtotal = calculateSubtotal(order);
double discount = discountCalculator.calculate(subtotal);
double total = subtotal * (1 - discount);
order.setSubtotal(subtotal);
order.setDiscount(discount);
order.setTotal(total);
repository.save(order);
logger.info("Order processed: " + order.getId());
}
private void validateOrder(Order order) throws InvalidOrderException {
if (order == null) {
throw new InvalidOrderException("Order null");
}
if (order.getItems().isEmpty()) {
throw new InvalidOrderException("No items");
}
}
private double calculateSubtotal(Order order) {
return order.getItems().stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum();
}
}
Заключение
Чистый код — это не цель, а путь. Требует постоянной практики, рефлексии и желания написать лучший код. Код живёт долго, и забота о его читаемости — это знак профессионализма и уважения к коллегам, которые с ним работают.