Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разбор запутанного кода
Реальный опыт
Да, я часто сталкиваюсь с запутанным кодом. Это нормальная ситуация в больших проектах, где несколько разработчиков работают годами. Расскажу о конкретном случае.
Пример из практики
Наследовал legacy систему платежей с 8-летней историей. Главный класс выглядел так:
public class PaymentProcessor {
public boolean processPayment(Map data, User u, int a, String ref, boolean flag) {
Integer am = (Integer) data.get("amount");
if (am != null && am > 0) {
if (u != null && u.getAc() != null) {
String key = u.getAc().getK() + "_" + ref;
Cache c = Cache.getInstance();
String cached = c.get(key);
if (cached != null && cached.equals("OK")) {
if (flag) return false;
return processTransaction(am, u, ref);
}
}
}
return false;
}
}
Методика разбора
1. Понимание цели
Сначала я выяснил: что ВООБЩЕ делает этот код? Платежи, авторизация, кэширование.
2. Добавление тестов
@Test
public void testDuplicatePaymentPrevention() {
Payment payment = new Payment(100, "REF123");
boolean first = processor.process(payment);
boolean second = processor.process(payment);
assertTrue(first);
assertFalse(second);
}
3. Пошаговое рефакторинг
private boolean isValidPayment(Map<String, Object> data, User user) {
Integer amount = (Integer) data.get("amount");
return amount != null && amount > 0 && user != null && user.getAccount() != null;
}
private String generateCacheKey(User user, String reference) {
return user.getAccount().getKey() + "_" + reference;
}
private boolean isDuplicatePayment(String cacheKey) {
Cache cache = Cache.getInstance();
String cached = cache.get(cacheKey);
return cached != null && cached.equals("OK");
}
public PaymentResult processPayment(PaymentRequest request) {
if (!isValidPayment(request)) {
return PaymentResult.INVALID_DATA;
}
String cacheKey = generateCacheKey(request.getUser(), request.getReference());
if (isDuplicatePayment(cacheKey)) {
return PaymentResult.DUPLICATE_PAYMENT;
}
return executeTransaction(request);
}
4. Введение доменных типов
public class PaymentRequest {
private final int amount;
private final User user;
private final String reference;
public PaymentRequest(int amount, User user, String reference) {
if (amount <= 0) throw new IllegalArgumentException("Invalid amount");
if (user == null) throw new IllegalArgumentException("User is required");
this.amount = amount;
this.user = user;
this.reference = reference;
}
}
public enum PaymentResult {
SUCCESS("Payment processed"),
DUPLICATE_PAYMENT("Payment already processed"),
INVALID_DATA("Invalid payment data");
private final String message;
PaymentResult(String message) { this.message = message; }
}
Инструменты
- IDE refactoring — Extract Method, Rename, Move
- Git blame — история кода:
git blame -L10,20 file.java - Tests — проверка, что ничего не сломал
- Code metrics — cyclomatic complexity
- Documentation — комментарии для непонятных мест
Практические советы
1. Читай с конца: Что возвращает метод? Это подскажет цель.
2. Добавь assert'ы:
assert amount > 0 : "Amount must be positive";
assert user != null : "User must be provided";
3. Создай диаграмму потока: User -> Validate -> Check Cache -> Process -> Update Cache
4. Обсуди с товарищем: Иногда свежий взгляд коллеги помогает лучше всего.
Результат
После рефакторинга код был:
- Читаем — понятна логика
- Тестируем — 90%+ покрытие
- Поддерживаем — легче добавлять фичи