← Назад к вопросам

С чем работал

1.3 Junior🔥 301 комментариев
#Soft Skills

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Описание поведения объекта в Java

Основные способы

Поведение объекта описывается несколькими способами:

1. Interface (Интерфейс)

Самый явный способ — интерфейс определяет контракт (какие методы должны быть и что они делают):

public interface PaymentProcessor {
    /**
     * Обрабатывает платёж
     * @param amount сумма платежа
     * @return результат обработки
     */
    boolean processPayment(double amount);
    
    /**
     * Проверяет статус платежа
     */
    PaymentStatus getStatus();
}

2. Abstract Class (Абстрактный класс)

Описывает поведение + состояние через методы и поля:

public abstract class Animal {
    private String name;
    
    // Конкретное поведение (реализовано)
    public void sleep() {
        System.out.println(name + " спит");
    }
    
    // Абстрактное поведение (подклассы должны реализовать)
    public abstract void makeSound();
}

3. Javadoc (Документация)

Самый полный и понятный способ — документировать поведение в Javadoc:

public class BankAccount {
    private double balance;
    
    /**
     * Пополняет счёт
     * 
     * @param amount сумма пополнения (должна быть > 0)
     * @throws IllegalArgumentException если amount <= 0
     * @throws InsufficientFundsException если депозит недоступен
     */
    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Сумма должна быть положительной");
        }
        balance += amount;
    }
    
    /**
     * Снимает со счёта
     * 
     * @param amount сумма снятия
     * @return true если успешно, false если недостаточно средств
     * @see #deposit(double)
     */
    public boolean withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            return true;
        }
        return false;
    }
}

4. Type Signature (Сигнатура типа)

Метод определяет входные и выходные данные:

public List<User> findActiveUsers(LocalDate since, int limit) {
    // Типизация делает поведение очевидным:
    // - входит: дата и лимит
    // - выходит: список пользователей
}

5. Exceptions (Исключения)

Описывают исключительные ситуации в поведении:

public User findById(UUID id) throws UserNotFoundException {
    // Если пользователь не найден -> выбрасываем исключение
    // Это часть контракта
}

6. Annotations (Аннотации)

Дополнительная информация о поведении:

public class PaymentService {
    @Deprecated(since = "2.0", forRemoval = true)
    public void processPaymentOld(double amount) {}
    
    @Override
    public String toString() { ... }
    
    @NotNull
    public String getReference() { ... }
}

Полный пример: UML Contract

public interface ShoppingCart {
    /**
     * Поведение корзины:
     * 
     * 1. ИНИЦИАЛИЗАЦИЯ
     *    - Пустая корзина при создании
     *    - userId установлен
     *    - createdAt = now()
     * 
     * 2. ДОБАВЛЕНИЕ ТОВАРА
     *    - addItem(Product, quantity) -> void
     *    - если товар уже есть -> увеличиваем количество
     *    - если quantity <= 0 -> выбрасываем IllegalArgumentException
     *    - total пересчитывается
     * 
     * 3. УДАЛЕНИЕ ТОВАРА
     *    - removeItem(productId) -> void
     *    - если товара нет -> silent (ничего не делаем)
     * 
     * 4. ОФОРМЛЕНИЕ
     *    - checkout() -> Order
     *    - если корзина пуста -> выбрасываем EmptyCartException
     *    - корзина очищается после успешного checkout
     */
    
    void addItem(Product product, int quantity);
    void removeItem(UUID productId);
    Order checkout();
    double getTotal();
}

Паттерн: Behavior Description

/**
 * Описываем поведение в комментарии класса
 */
public class RateLimiter {
    /**
     * ПОВЕДЕНИЕ:
     * - Ограничивает количество операций в единицу времени
     * - Если лимит превышен -> выбрасываем RateLimitExceededException
     * - Каждые N миллисекунд счётчик обнуляется
     * 
     * ПРИМЕР ИСПОЛЬЗОВАНИЯ:
     * RateLimiter limiter = new RateLimiter(10, Duration.ofSeconds(1));
     * for (int i = 0; i < 10; i++) {
     *     limiter.checkRate();  // ОК
     * }
     * limiter.checkRate();  // Выбрасит исключение
     */
    
    public void checkRate() throws RateLimitExceededException { }
}

Best Practices

  1. Используй интерфейсы для явного описания контракта
  2. Документируй Javadoc поведение, граничные случаи, исключения
  3. Явные исключения — выбрасывай специфичные исключения
  4. Типизация — типы параметров и возвращаемых значений скажут о многом
  5. Тесты — тесты демонстрируют ожидаемое поведение
  6. Аннотации — @Nullable, @NotNull, @Deprecated помогают

Помните: хороший код самодокументируется через структуру, типы и имена!