You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clean Architecture中如何设置实体间关系?博客场景架构设计疑问

针对Clean Architecture博客系统实体设计的解答

问题1:Blog Domain同时设User和Post实体,Auth Domain如何处理?

不要在Blog Domain里定义完整的User实体——Blog Domain只需要和自身业务相关的User属性与行为,比如authorId、getDisplayName()这类和博客创作相关的内容,不需要包含密码、权限验证这类Auth Domain专属的逻辑。Auth Domain里的User实体专注于身份认证相关的属性(如密码哈希、登录凭证)和行为(如verifyPassword())。

两个Domain的User实体通过**唯一标识(比如userId)**关联,而不是共享同一个类。这样既符合Clean Architecture中“每个Domain只关注自身核心业务”的原则,也避免了Domain间的耦合。

问题2:仅Blog Domain设Post实体,如何关联User?

Post实体只需要持有User的唯一标识(如authorId),不需要直接依赖Auth Domain的User实体。当需要获取用户的展示信息(比如作者名称)时,通过Blog Domain的Repository接口来获取——这个接口由外层的基础设施层实现,基础设施层可以调用Auth Domain的服务来获取所需的用户数据。

举个简单的代码示例:

// Blog Domain的Post实体
public class Post {
    private String id;
    private String title;
    private String content;
    private String authorId; // 仅持有用户ID

    // 业务逻辑:验证作者是否有权限发布
    public boolean canPublish(AuthorPermissionChecker checker) {
        return checker.hasPermission(authorId);
    }
}

// Blog Domain的Repository接口
public interface PostAuthorInfoRepository {
    AuthorInfo getAuthorInfoById(String authorId);
}

// 基础设施层实现接口,调用Auth服务
public class AuthBasedAuthorInfoRepository implements PostAuthorInfoRepository {
    private final AuthUserService authUserService;

    public AuthorInfo getAuthorInfoById(String authorId) {
        AuthUser user = authUserService.getUserById(authorId);
        return new AuthorInfo(user.getId(), user.getDisplayName());
    }
}

这种方式既保持了Blog Domain的独立性,又能通过依赖反转原则实现与User的数据关联。

问题3:两个Domain分别设User实体,如何避免代码重复?

首先要明确:两个Domain的User实体并不是“重复代码”——它们服务于不同的业务场景,属性和行为本来就应该有差异。但如果确实有一些通用的属性(比如userId、displayName),可以提取到共享的基础Domain包(比如Shared.Domain)中,作为一个值对象(Value Object)或者基础实体类,让两个Domain的User实体继承或组合这个基础类。

比如:

// Shared Domain的基础值对象
public class UserIdentity {
    private final String id;
    private final String displayName;

    // 构造器、getter等
}

// Auth Domain的User实体
public class AuthUser {
    private UserIdentity identity;
    private String passwordHash;
    private LocalDateTime lastLoginTime;

    // 身份认证相关行为:verifyPassword()等
}

// Blog Domain的Author实体
public class Author {
    private UserIdentity identity;
    private int postCount;

    // 博客相关行为:increasePostCount()等
}

这种方式既保留了各Domain的独立性,又复用了通用的属性逻辑,同时避免了Domain间的直接耦合。另外,不要为了复用而强行合并实体——每个Domain的实体必须优先满足自身的业务需求,复用是次要的。


内容的提问来源于stack exchange,提问作者Eternal Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 05:22:18