【问题标题】:How to ensure the integrity of domain model in DDD [closed]如何确保 DDD 中域模型的完整性
【发布时间】:2014-07-09 14:37:58
【问题描述】:

我有一个名为 country 的域实体,其结构如下

 public class Country : Entity
    {
        public Country()
        {
            States=new List<State>();
        }
        public string CountryName { get; set; }
        public string CountyCode { get; set; }

        public virtual ICollection<State> States { get; private set; }

        public void AddNewState(State state)
        {
            if(IsDuplicateStateExists(state.GetHashCode())) throw new ApplicationOperationException(Messages.Validation_DuplicateState){HttpCode = 409};

            States.Add(state);
        }

        bool IsDuplicateStateExists(int hashCode)
        {
           return States.Any(x => x.GetHashCode() == hashCode);
        }

        public State GetStateById(int stateId)
        {
            return States.FirstOrDefault(x => x.Id == stateId);
        }

        public void DeleteState(int stateId)
        {
            var state = GetStateById(stateId); 
            if(state==null) return;
            state.CountryId = 0; // This is for informing EF to delete this object Check Orphan entities in EF
            States.Remove(state);
        }

        public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List<ValidationResult>();

            if (CountryName.Length < 3) results.Add(new ValidationResult(Messages.Validation_CountryNameRequired,new String[]{"CountryName"}));
            if (CountyCode.Length < 2) results.Add(new ValidationResult(Messages.Validation_CountryCodeRequired, new String[] { "CountyCode" }));
            return results;
        }
    }

在这里,我对这个实体的设计几乎没有疑问, 1.) 实体可以抛出错误吗?

2.) 将验证(而非业务规则)逻辑放入实体中是否是个好主意

3.) “国家有州,每个州都必须有县”, 如果这是设计规范中的一条规则,Addnewstate(),IsDuplicateStatesExists(),RemoveStates () 有资格保留在国家实体内部,或者我应该转移到应用程序服务

【问题讨论】:

  • 这是一个太多的问题,它可能属于程序员而不是 StackOverflow,后者更真实,更少概念。
  • @ArtB,几乎每个与 DDD 相关的问题都是基于意见的,因为它是一种模式,具有不同的实现风格。在这里,我根据少数给定的事实询问了我的实施是否正确。所有的问题都没有太大的不同,但都是相关的。
  • DDD 更加处理和开放,所以我想说程序员是更好的地方。不要误会我的意思,我喜欢你的问题,这不是恕我直言(而且不仅仅是我的)错误的地方。他们删除了标记问题以转移到程序员的选项,因此您必须自己做。

标签: asp.net-mvc domain-driven-design ddd-repositories


【解决方案1】:

1.) 实体可以抛出错误吗?

是的,当然。违反业务规则时可以抛出异常。

2.) 将验证(而非业务规则)逻辑放入实体中是否是个好主意

我更愿意在实体中只放置业务验证。所以我不会验证实体中的字符串长度等逻辑。上层应该验证非业务逻辑。但我认为在实体中使用 [Required][StringLength] 之类的 DataAnnotations 是个好主意,因为它们非常简单,让我们的生活更轻松:P

3.) “国家有州,每个州都必须有县”,如果这是设计规范中的一条规则,Addnewstate(),IsDuplicateStatesExists(),RemoveStates () 有资格保留在国家实体内部,或者我应该搬到应用服务。

保持在Country 实体内。但是您的实现不正确。 两个不同的实体可以产生相同的哈希码!如果您正确实现了State 类的GetHashCodeEquals 方法,则可以将States 属性设置为一个集合(ISet&lt;T&gt;)。但我更愿意仅根据州名检查重复项。

【讨论】:

    【解决方案2】:

    实体只是数据传输对象。它们告诉 Entity Framework 数据库表应该是什么样子,并为 Entity Framework 提供一个地方来转储它从该表中选择的数据。因此,它们应该只具有与数据库相关的业务逻辑。例如,如果字符串列不能为空,您可以将 [Required] 属性添加到您的属性。超出此范围的任何东西都属于其他地方

    “其他地方”可能是您的存储库、服务或视图模型。它是与如何检索实体相关的业务逻辑,例如,您将其放入存储库或服务中。如果是与用户如何在表单中输入数据相关的业务逻辑,则属于视图模型。

    【讨论】:

    • 我不是在问 EF 或其相关技术,我是在问域驱动设计概念,“实体只是数据传输对象”这个语句在域驱动设计中如何有效,是个好主意将 POCO 视为我们领域模型中的领域实体
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多