整洁架构中的仓储模式
实现仓储模式以抽象数据访问,让用例能够与数据持久化交互,而无需了解其细节。
整洁架构中的仓储模式 是 CoddyKit 上的免费 Clean Architecture & Design Patterns in Practice 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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.
常见问题解答
「整洁架构中的仓储模式」课时是免费的吗?
是的 — 「整洁架构中的仓储模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Clean Architecture & Design Patterns in Practice 课程的其余内容,请升级到 CoddyKit PRO。 Clean Architecture & Design Patterns in Practice 课程共包含 4 节课。
「整洁架构中的仓储模式」这节课中我会学到什么?
实现仓储模式以抽象数据访问,让用例能够与数据持久化交互,而无需了解其细节。 你通过在浏览器中直接运行的动手代码来练习 Clean Architecture & Design Patterns in Practice,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Clean Architecture & Design Patterns in Practice 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Clean Architecture & Design Patterns in Practice 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「整洁架构中的仓储模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Clean Architecture & Design Patterns in Practice 课中编写并运行代码吗?
能。每节 Clean Architecture & Design Patterns in Practice 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 整洁架构中的仓储模式
- 面向外部系统的网关接口
- 数据映射器与 DTO
- 面向第三方 API 的防腐层