0Pricing
Clean Architecture & Design Patterns in Practice · レッスン

Clean ArchにおけるRepositoryパターン

Repositoryパターンを実装してデータアクセスを抽象化し、Use Casesが詳細を知らずにデータの永続化とやり取りできるようにします。

「Clean ArchにおけるRepositoryパターン」はCoddyKit上の無料Clean Architecture & Design Patterns in Practiceレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはClean Architecture & Design Patterns in Practice学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Clean Architecture & Design Patterns in Practiceコースには全4レッスンが含まれています。

このレッスンの一部はまだ翻訳されておらず、英語で表示されています。

What's the Repository Pattern?

In Clean Architecture, we want our core business logic (Use Cases) to be independent of external details like databases or web frameworks.

The Repository Pattern helps achieve this by abstracting the way data is stored and retrieved. It acts as a mediator between the domain and data mapping layers.

The Problem: Direct Data Access

Imagine your Use Case directly querying a database or calling an ORM (Object-Relational Mapper) like Hibernate or Entity Framework.

  • Your Use Case becomes coupled to the database technology.
  • Changing the database means changing the Use Case.
  • Testing Use Cases requires a live database connection.

This violates the Dependency Rule of Clean Architecture, which states that dependencies should only point inwards.

Introducing the Repository Interface

The solution is to define an interface (a contract) for data access within your Use Case layer. This interface is the Repository.

It declares methods like findById(), save(), or findAll(). The Use Case layer owns this interface, meaning it defines what data operations it needs.

Code: User & Repository Interface

First, we define a simple User entity. Then, the UserRepository interface specifies the contract for how we'll interact with User data.

public class User {
  String id;
  String name;
  public User(String id, String name) {
    this.id = id; this.name = name;
  }
  public String getId() { return id; }
  public String getName() { return name; }
  @Override public String toString() {
    return name + " (" + id + ")";
  }
}

public interface UserRepository {
  User findById(String id);
  void save(User user);
}

public class Main {
  public static void main(String[] args) {
    System.out.println("User entity and UserRepository interface defined.");
  }
}

Repository Implementations

While the interface lives in your core domain, the concrete implementation of the Repository lives in an outer layer, typically the 'Interface Adapters' or 'Frameworks/Drivers' layer.

This implementation knows the details of the specific persistence technology (e.g., SQL database, NoSQL database, external API, or even in-memory storage).

Code: In-Memory Implementation

Here's an example of an InMemoryUserRepository. It implements the UserRepository interface using a simple HashMap, simulating a database for testing or simple applications.

// Assume User and UserRepository exist

import java.util.HashMap;
import java.util.Map;

public class InMemoryUserRepository implements UserRepository {
  private final Map<String, User> users = new HashMap<>();

  @Override
  public User findById(String id) {
    return users.get(id);
  }

  @Override
  public void save(User user) {
    users.put(user.getId(), user);
  }
}

public class Main {
  public static void main(String[] args) {
    InMemoryUserRepository repo = new InMemoryUserRepository();
    User newUser = new User("001", "Charlie");
    repo.save(newUser);

    User found = repo.findById("001");
    System.out.println("Found user: " + found.getName());
  }
}

Use Cases & Repositories

A Use Case receives an instance of the UserRepository interface through dependency injection (e.g., via its constructor).

The Use Case then calls methods on this interface, completely unaware of whether it's talking to an in-memory map, a SQL database, or a remote API. This is true decoupling!

Code: Use Case with Repository

This CreateUserUseCase depends only on the UserRepository interface, not its specific implementation. This makes it highly testable and flexible.

// Assume User, UserRepository, InMemoryUserRepository exist

public class CreateUserUseCase {
  private final UserRepository userRepository;

  public CreateUserUseCase(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public User execute(String id, String name) {
    User newUser = new User(id, name);
    userRepository.save(newUser);
    return newUser;
  }
}

public class Main {
  public static void main(String[] args) {
    // Inject the in-memory implementation
    UserRepository repo = new InMemoryUserRepository();
    CreateUserUseCase createUser = new CreateUserUseCase(repo);

    User createdUser = createUser.execute("002", "Diana");
    System.out.println("Created user: " + createdUser.getName());

    User found = repo.findById("002");
    System.out.println("Verified in repo: " + found.getName());
  }
}

Benefits of Repositories in Clean Arch

Using the Repository Pattern offers significant advantages:

  • Decoupling: Business rules are isolated from data storage details.
  • Testability: Use Cases can be tested with mock or in-memory repositories.
  • Flexibility: Easily swap data sources (e.g., from SQL to NoSQL) without changing core logic.
  • Maintainability: Changes in data access technology are localized to repository implementations.

Quick Check on Repositories

The Repository Pattern is a cornerstone for maintaining separation of concerns in Clean Architecture.

Repository Pattern: Recap

You've learned about the Repository Pattern and its crucial role in Clean Architecture!

  • It abstracts data access from your core business logic.
  • It uses an interface (owned by the domain) and concrete implementations (in outer layers).
  • This approach greatly enhances decoupling, testability, and flexibility.

By implementing Repositories, you ensure your Use Cases remain clean, focused, and independent of external data storage mechanisms.

よくある質問

「Clean ArchにおけるRepositoryパターン」レッスンは無料ですか?

はい。「Clean ArchにおけるRepositoryパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Clean Architecture & Design Patterns in Practiceコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Clean Architecture & Design Patterns in Practiceコースには全4レッスンが含まれています。

「Clean ArchにおけるRepositoryパターン」で何を学びますか?

Repositoryパターンを実装してデータアクセスを抽象化し、Use Casesが詳細を知らずにデータの永続化とやり取りできるようにします。 ブラウザで直接実行するハンズオンコードでClean Architecture & Design Patterns in Practiceを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Clean Architecture & Design Patterns in Practiceを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのClean Architecture & Design Patterns in Practiceは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「Clean ArchにおけるRepositoryパターン」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このClean Architecture & Design Patterns in Practiceレッスンでコードを書いて実行できますか?

はい。すべてのClean Architecture & Design Patterns in Practiceレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Clean ArchにおけるRepositoryパターン
  2. 外部システム向けGatewayインターフェース
  3. Data MapperとDTO
  4. サードパーティAPI向け腐敗防止層
← Clean Architecture & Design Patterns in Practiceに戻る