Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование package в Java
Пакеты — это организационный механизм в Java для группировки связанных классов и контроля видимости.
Что такое package
Пакет — это директория классов с именованным пространством имён.
package com.example.domain; // Класс находится в com/example/domain/
public class User {
// ...
}
Случаи использования package
1. Организация кода по функциональности (слои архитектуры)
com.example.app
├── domain // Бизнес-логика
│ ├── User.java
│ ├── Order.java
│ └── OrderService.java
├── application // Use Cases
│ ├── CreateOrderUseCase.java
│ └── FindOrderUseCase.java
├── infrastructure // Базаданные, API, кэш
│ ├── PostgresUserRepository.java
│ ├── HttpPaymentService.java
│ └── RedisCache.java
└── presentation // REST контроллеры
├── UserController.java
└── OrderController.java
Это следует onion architecture (луковая архитектура). Зависимости идут только внутрь (presentation → application → domain).
2. Контроль доступа через модификаторы доступа
// package-private (видно только внутри пакета)
class InternalHelper { // без public
// ...
}
// public (видно везде)
public class User {
// ...
}
public class User {
// package-private (видно только в пакете com.example.domain)
void internalMethod() { }
// public (видно везде)
public void publicMethod() { }
}
3. Разделение по компонентам (микросервисная архитектура)
com.example
├── auth
│ ├── domain
│ ├── application
│ ├── infrastructure
│ └── presentation
├── users
│ ├── domain
│ ├── application
│ ├── infrastructure
│ └── presentation
└── orders
├── domain
├── application
├── infrastructure
└── presentation
Каждый компонент независим и может быть отделён в отдельный микросервис.
4. Изоляция внутренних деталей реализации
// com.example.users.domain
public interface UserRepository {
User findById(String id);
}
// com.example.users.infrastructure
class PostgresUserRepository implements UserRepository {
// внутренняя реализация, не используется напрямую
@Override
public User findById(String id) { }
}
Возможно заменить PostgresUserRepository на MongoUserRepository без изменения кода, который использует интерфейс.
Правила именования package
Используй обратное доменное имя:
// ✅ Правильно
package com.company.product.domain;
package org.springframework.boot;
package com.google.guava;
// ❌ Неправильно
package domain; // слишком общее
package myapp.domain; // не обратный домен
package com.mycompany.verylong.nested.structure; // слишком глубоко
Best Practices
1. Не делай слишком глубокие package иерархии
// ❌ Плохо — слишком глубоко
package com.example.app.domain.entities.user.models.dto;
// ✅ Хорошо — достаточно глубоко
package com.example.users.domain;
2. Используй package-private для скрытия реализации
public class UserService {
private InternalValidator validator; // package-private класс
public void createUser(CreateUserRequest req) {
validator.validate(req); // видно только в пакете
}
}
class InternalValidator { // package-private
// ...
}
3. Разделяй API и реализацию
com.example.users
├── api
│ ├── UserRepository.java // публичный интерфейс
│ └── UserService.java
└── impl
└── PostgresUserRepository.java // внутренняя реализация
4. Избегай циклических зависимостей между пакетами
// ❌ Проблема
// users → orders (импортирует OrderService)
// orders → users (импортирует UserService)
// ✅ Решение
// users → events (публикует события)
// orders → events (слушает события)
Пример правильной структуры проекта
src/main/java/com/example/shop
├── shared
│ ├── domain
│ │ ├── DomainEvent.java
│ │ └── Repository.java
│ └── application
│ └── ApplicationService.java
├── users
│ ├── domain
│ │ ├── User.java
│ │ ├── UserId.java
│ │ └── UserRepository.java (интерфейс)
│ ├── application
│ │ ├── CreateUserUseCase.java
│ │ └── FindUserUseCase.java
│ ├── infrastructure
│ │ └── PostgresUserRepository.java (реализация)
│ └── presentation
│ └── UserController.java
└── orders
├── domain
├── application
├── infrastructure
└── presentation
Когда НЕ использовать package
Не переусложняй:
// ❌ Переусложнено для маленького проекта
com.example.calculator.domain.math.operations.arithmetic.addition
// ✅ Достаточно
com.example.calculator.domain
Вывод
Используй package для:
- Организации кода по слоям архитектуры
- Контроля доступа через package-private модификатор
- Изоляции реализации от публичного API
- Разделения компонентов в больших проектах
- Избегания конфликтов имён между проектами
Пакеты — это не просто папки, это инструмент проектирования архитектуры. Правильная структура package помогает другим разработчикам понять код и его зависимости.