2013-12-09 74 views
1

我想展開這個問題When to update audit fields? DDD如何更新域模型中的審計字段?

在我的域模型中,這可能不是正確的位置,但我們擁有屬性Created和UsedBy,兩者都是User類型,都是值對象。

我是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,這可以接受嗎?處理更新審計屬性的更好方法是什麼?有更好的方法,即使用事件嗎?

我承認這有點主觀,但會感謝任何人可以提供幫助!

回答

1

解決方案的「框架」

A.暴露有額外的參數每個構造函數和命令的方法。 喜歡:

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

    _colors = new SpritePaletteColors(); 
    createdBy(user) 
} 

public void UpdateName(string value, User user) 
{ 
    this.Name = value; 
    modifiedBy(user); 
} 

internal void modifiedBy(User value) 
{ 
    this.CreatedBy = value; 
    this.CreatedDate = DateTime.UtcNow; 
} 

在這種情況下,每次應用層操縱域模型,審計字段被更新。但是這可能看起來cubersome當應用層調用幾個命令的方法,如:

//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.暴露額外的審計字段更新方法。

像:

//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); 
} 

但我怕有時我們可能會忘記調用此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); 
} 
1

在你上面鏈接的問題,CreatedByUpdatedBy是領域層的一部分,因爲在實際領域的會議實際上由別人安排。

在您的設置(Sprites)中,CreatedByUpdatedBy似乎不太可能是底層圖形域的一部分。因此,CreatedBy/UpdatedBy屬性僅用於記帳/審計,因此是純粹的應用程序級別問題,應僅在應用程序級別處理。在Java中,你通常會通過一些攔截器更新這些標誌,但我不確定如何在C#中執行此操作。也許可以更新存儲庫中的這些字段(通過讓應用程序在工作單位或類似的地方註冊當前用戶)。

相關問題