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

聚合根应使用接口还是类?附代码示例及选型困惑

选择聚合根实现方案:抽象类 vs 标记接口

我在做DDD项目的时候也纠结过类似的问题,这俩方案各有适用场景,得结合你的项目需求来选,下面给你拆解一下:

一、带领域事件的抽象类 AggregateRoot

优点

  • 开箱即用的一致性:所有继承它的聚合根直接拥有领域事件的管理能力,不用重复写_domainEvents集合、AddDomainEvent、ClearEvents这些基础代码,能保证所有聚合根的事件处理逻辑统一,避免出现有的聚合根忘了实现ClearEvents导致事件重复发布的坑。
  • 符合DDD实践:领域事件本来就是聚合根的核心能力之一,大多数DDD项目里,几乎所有聚合根都会产生或处理领域事件,这种抽象类能帮你省掉大量重复劳动。

缺点

  • 单继承限制:C#是单继承语言,如果你的某个聚合根因为特殊业务需求必须继承另一个类(虽然在DDD的规范里这种情况很少见,但不排除例外),这个抽象类就会让你陷入两难。
  • 冗余代码:如果有部分聚合根完全不需要处理领域事件,继承这个抽象类就会带上无用的事件管理代码,有点多余。

二、标记接口 IAggregateRoot

优点

  • 极致灵活:只是一个标记,没有任何继承限制,你可以给任何类加上这个接口来标识它是聚合根,不管它有没有领域事件,也不管它是否继承了其他类。
  • 架构层面的约定:可以在仓储层、领域服务层用这个接口做统一的筛选或处理,比如仓储只处理实现了IAggregateRoot的对象,方便架构扩展。

缺点

  • 重复代码风险:每个需要领域事件的聚合根都得自己实现一遍事件管理逻辑,很容易出现不一致的实现——比如有的用List,有的用HashSet,或者有的聚合根漏写了ClearEvents方法,后期维护成本高。

三、怎么选?

  1. 优先选抽象类(大多数场景):如果你的项目里所有/绝大多数聚合根都需要处理领域事件,而且没有多继承的需求,直接用那个带领域事件的抽象类就好。这是DDD项目里最常见的做法,能帮你减少重复工作,保证事件处理的一致性。
  2. 选标记接口(特殊场景):如果你的聚合根需求差异很大,有些完全不需要领域事件,或者有聚合根必须继承其他类,那标记接口更合适。另外,如果你用的是C# 8及以上版本,还可以给接口加默认实现,或者结合扩展方法来补上事件管理的逻辑,兼顾灵活性和代码复用:
public interface IAggregateRoot
{
    IReadOnlyList<IDomainEvent> DomainEvents { get; }
    void AddDomainEvent(IDomainEvent newEvent);
    void ClearEvents();
}

// 用扩展方法实现默认逻辑
public static class AggregateRootExtensions
{
    private static readonly ConditionalWeakTable<IAggregateRoot, List<IDomainEvent>> _eventStore = new();

    public static IReadOnlyList<IDomainEvent> DomainEvents(this IAggregateRoot root)
    {
        return _eventStore.TryGetValue(root, out var events) ? events.AsReadOnly() : Array.Empty<IDomainEvent>();
    }

    public static void AddDomainEvent(this IAggregateRoot root, IDomainEvent newEvent)
    {
        var events = _eventStore.GetOrCreateValue(root);
        events.Add(newEvent);
    }

    public static void ClearEvents(this IAggregateRoot root)
    {
        if (_eventStore.TryGetValue(root, out var events))
        {
            events.Clear();
        }
    }
}

这种方式既保留了接口的灵活性,又避免了重复写事件管理代码,适合需要兼顾多种场景的项目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:17:27