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

Приведи пример использования локального репозитория

1.8 Middle🔥 81 комментариев
#Основы Java

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

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

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

Приведи пример использования локального репозитория

Локальный репозиторий — это паттерн проектирования (Repository Pattern), который инкапсулирует логику доступа к данным, скрывая детали хранилища от бизнес-логики. Рассмотрим полный пример с использованием в памяти хранилища.

Концепция

Локальный репозиторий — это in-memory хранилище (обычно HashMap), которое используется для тестирования, прототипирования или простых приложений без БД.

Пример 1: Простой In-Memory репозиторий

public class User {
    private UUID id;
    private String email;
    private String name;
    
    public User(UUID id, String email, String name) {
        this.id = id;
        this.email = email;
        this.name = name;
    }
    
    public UUID getId() { return id; }
    public String getEmail() { return email; }
    public String getName() { return name; }
}
public interface UserRepository {
    void save(User user);
    User findById(UUID id);
    List<User> findAll();
    void delete(UUID id);
    Optional<User> findByEmail(String email);
}
public class LocalUserRepository implements UserRepository {
    private final Map<UUID, User> store = new HashMap<>();
    
    @Override
    public void save(User user) {
        store.put(user.getId(), user);
    }
    
    @Override
    public User findById(UUID id) {
        return store.get(id);
    }
    
    @Override
    public List<User> findAll() {
        return new ArrayList<>(store.values());
    }
    
    @Override
    public void delete(UUID id) {
        store.remove(id);
    }
    
    @Override
    public Optional<User> findByEmail(String email) {
        return store.values().stream()
            .filter(u -> u.getEmail().equals(email))
            .findFirst();
    }
}

Пример 2: Использование в сервисе

public class UserService {
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public void registerUser(String email, String name) {
        if (userRepository.findByEmail(email).isPresent()) {
            throw new UserAlreadyExistsException("Email already registered");
        }
        
        User newUser = new User(UUID.randomUUID(), email, name);
        userRepository.save(newUser);
    }
    
    public Optional<User> findUser(UUID id) {
        return Optional.ofNullable(userRepository.findById(id));
    }
    
    public void deleteUser(UUID id) {
        userRepository.delete(id);
    }
}

Пример 3: Использование в тестах

@Test
void testRegisterUser() {
    UserRepository repository = new LocalUserRepository();
    UserService service = new UserService(repository);
    
    service.registerUser("alice@example.com", "Alice");
    
    Optional<User> found = repository.findByEmail("alice@example.com");
    assertTrue(found.isPresent());
    assertEquals("Alice", found.get().getName());
}

@Test
void testDuplicateEmailFails() {
    UserRepository repository = new LocalUserRepository();
    UserService service = new UserService(repository);
    
    service.registerUser("alice@example.com", "Alice");
    
    assertThrows(UserAlreadyExistsException.class, () -> 
        service.registerUser("alice@example.com", "Alice2")
    );
}

Пример 4: Более сложный локальный репозиторий с фильтрацией

public class LocalProductRepository implements ProductRepository {
    private final Map<UUID, Product> store = new HashMap<>();
    
    @Override
    public void save(Product product) {
        store.put(product.getId(), product);
    }
    
    @Override
    public List<Product> findByCategory(String category) {
        return store.values().stream()
            .filter(p -> p.getCategory().equals(category))
            .collect(Collectors.toList());
    }
    
    @Override
    public List<Product> findByPriceRange(double minPrice, double maxPrice) {
        return store.values().stream()
            .filter(p -> p.getPrice() >= minPrice && p.getPrice() <= maxPrice)
            .collect(Collectors.toList());
    }
}

Сценарии использования

  1. Тестирование — быстрые unit-тесты без базы данных
  2. Разработка — быстрое прототипирование без настройки БД
  3. Демонстрация — простая демо-версия приложения
  4. Кеширование — локальный кеш часто используемых данных
  5. Микросервисы в памяти — для локальной разработки

Преимущества

  • Простота — легко реализуется и понимается
  • Скорость тестов — нет затрат на БД
  • Полиморфизм — сервис не знает о реализации репозитория
  • Гибкость — легко менять реализацию

Недостатки

  • Нет персистентности — данные теряются при перезагрузке
  • Нет масштабируемости — не подходит для больших объемов
  • Потокобезопасность — необходима синхронизация для многопоточности
  • Нет транзакций — сложная бизнес-логика может сломаться

Для многопоточности

public class ThreadSafeLocalUserRepository implements UserRepository {
    private final Map<UUID, User> store = Collections.synchronizedMap(new HashMap<>());
    // Или использовать ConcurrentHashMap
}

Локальный репозиторий — это простой, но мощный инструмент для разработки и тестирования Java приложений, обеспечивающий чистую архитектуру и слабую связанность компонентов.

Приведи пример использования локального репозитория | PrepBro