Domain driven design 如何更新域模型中的审核字段?

Domain driven design 如何更新域模型中的审核字段?,domain-driven-design,Domain Driven Design,我想进一步讨论这个问题 在我的域模型中,这可能不是它的正确位置,但是我们有CreatedBy和ModifiedBy的属性,这两个类型都是User,都是value对象 我是DDD新手,不知道哪一层负责更新这些属性。。。数据?域名?还是申请 在上面链接的问题中,他们提到使用事件更新这些属性。。。那么假设这些字段在域上是可更新的 这是我班的一个例子 public class SpritePalette { private readonly SpritePaletteColors _colors

我想进一步讨论这个问题

在我的域模型中,这可能不是它的正确位置,但是我们有CreatedBy和ModifiedBy的属性,这两个类型都是User,都是value对象

我是DDD新手,不知道哪一层负责更新这些属性。。。数据?域名?还是申请

在上面链接的问题中,他们提到使用事件更新这些属性。。。那么假设这些字段在域上是可更新的

这是我班的一个例子

public class SpritePalette
{
    private readonly SpritePaletteColors _colors;

    public string Id { get; private set; }
    public string Name { get; private set; }
    public SpritePaletteColors Colors { get { return _colors; } }
    public bool IsPublic { get; private set; }
    public User CreatedBy { get; private set; }
    public DateTime CreatedDate { get; private set; }
    public User ModifiedBy { get; private set; }
    public DateTime ModifiedDate { get; private set; }

    public SpritePalette(
        string name)
    {
        this.Name = name;
        this.IsPublic = false;

        _colors = new SpritePaletteColors();
    }

    internal void UpdateId(string value)
    {
        Validate.IsNotEmpty(value, "Id is required.");

        this.Id = value;
    }

    public void UpdateName(string value)
    {
        this.Name = value;
    }   

    public void MarkAsCreated(User value)
    {
        this.CreatedBy = value;
        this.CreatedDate = DateTime.UtcNow;
    }

    public void MarkAsModified(User value)
    {
        this.ModifiedBy = value;
        this.ModifiedDate = DateTime.UtcNow;
    }

    public bool HasColor(string color)
    {
        return _colors.HasColor(color);
    }

    public void AddColor(string color)
    {
        _colors.AddColor(color);
    }

    public void RemoveColor(string color)
    {
        _colors.RemoveColor(color);
    }

    public void UpdateIsPublic(bool value)
    {
        this.IsPublic = value;
    }
}
我使用了两种方法,一种是将模型标记为已创建(更新CreatedBy和CreatedDate),另一种是将模型标记为已修改的类似方法

在DDD方面,这是否可以接受?处理更新此类审核属性的更好方法是什么?是否有更好的方法,即使用事件


我承认这有点主观,但如果有人能提供帮助,我将不胜感激

具有“框架”的解决方案

A.使用额外参数公开每个构造函数和命令方法。 比如:

在这种情况下,每次应用层操作域模型时,审计字段都会更新。但是,当应用程序层调用以下几种命令方法时,这可能会显得有些笨拙:

//application layer
public void update(String name, String description, ....other attributes,User user) [
    //retrieve SpritePalette
    SpritePalette.updateName(name, user);
    SpritePalette.updateDescription(description, user);//passes user again
    //other command methods invocation   //passes user again & again
}
B.公开额外的审核字段更新方法

比如:

但我担心有时我们可能会忘记调用这个modifiedBy()方法

没有“框架”的解决方案

也许我们应该使用另一套模型。如果我们将更新行为建模为事件呢?核心域不需要审计字段。审计字段通常是查询需求所需要的,比如“我想看看谁修改了这个东西”

让我们把它们分开:

class UpdateNameEvent {
    string SpritePaletteId;
    string name;
    User user;
    Date when;
}

class SpritePalette{
    on(UpdateNameEvent event) {
         this.Name = event.name();//no user involved
    }
}

 //application layer
public void update(String name, User user) [
    //retrieve SpritePalette
    var event = new UpdateNameEvent(name, user);
    SpritePalette.on();
    //other command methods invocation   
    events.save(event); //save the events
    repository.update(SpritePalette);
}

public List<SpritePaletteEvent> list(string id) {
    return events.list(id);
}
类UpdateNameEvent{
弦小花瓣;
字符串名;
用户;
日期和时间;
}
类斜板{
打开(UpdateNameEvent事件){
this.Name=event.Name();//不涉及任何用户
}
}
//应用层
公共无效更新(字符串名称、用户)[
//取回小喷灯
var事件=新的UpdateNameEvent(名称、用户);
SpritePalette.on();
//其他命令方法调用
events.save(event);//保存事件
repository.update(spritepalete);
}
公共列表(字符串id){
返回事件列表(id);
}

在您上面链接的问题中,
CreatedBy
UpdatedBy
是域层的一部分,因为在实际域中,会议实际上是由某人安排的

在您的设置中(精灵)似乎
CreatedBy
UpdatedBy
不太可能是底层图形域的一部分。因此
CreatedBy
/
UpdatedBy
属性仅用于簿记/审核,因此是纯应用程序级别的问题,应该仅在应用程序级别处理它们。在Java中,您可以通常通过某个拦截器更新这些标志,但我不确定如何在C#中做到这一点。也许可以在存储库中更新这些字段(通过让应用程序在工作单元或类似单元中注册当前用户)

 //application layer
public void update(String name, String description, ....other attributes,User user) [
    //retrieve SpritePalette
    SpritePalette.updateName(name);
    SpritePalette.updateDescription(description);
    //other command methods invocation   
    SpritePalette.modifiedBy(user);
}
class UpdateNameEvent {
    string SpritePaletteId;
    string name;
    User user;
    Date when;
}

class SpritePalette{
    on(UpdateNameEvent event) {
         this.Name = event.name();//no user involved
    }
}

 //application layer
public void update(String name, User user) [
    //retrieve SpritePalette
    var event = new UpdateNameEvent(name, user);
    SpritePalette.on();
    //other command methods invocation   
    events.save(event); //save the events
    repository.update(SpritePalette);
}

public List<SpritePaletteEvent> list(string id) {
    return events.list(id);
}