【问题标题】:Can implement stateful Domain Service in DDD (Domain Driven Design)?可以在 DDD(域驱动设计)中实现有状态的域服务吗?
【发布时间】:2013-10-06 05:32:00
【问题描述】:

实体有'Note'域对象。

@Entity
@Getter
@Setter
class Note {
    @ManyToOne(..)
    private User writer;

    private String title;
    private String content;
    ... some attributes ...

    private Date createdAt;
    private Date updatedAt;

    private User latestModifier;

    ... some methods ...
}

我认为'NoteEditor' 用于处理打开和保存笔记,如下所示。

class NoteEditorImpl implements NoteEditor {

    private NoteRepository repository;
    private ApplicationPublisher publisher;

    private Note note;      // opened note.
    private User user;      // operator.

    NoteEditorImpl(ApplicationContext context, User user) {

        this.repository = context.getBean(NoteRepository.class);
        this.publisher = context.getBean(ApplicationPublisher.class);

        this.user = user;
    }

    NoteEditor open(Note note) {
        if ( !note.canBeEditedBy(user) ) {
            throw new ServiceRuntimeException('... cause message ...');
        }

        this.note = note;

        return this;
    }

    NoteEditor setTitle(String title) {
        ... 
        this.note.setTitle(title);
        return this;
    }

    ...

    Note save() {
        this.note.setLatestModifier(this.user);
        this.note.setUpdatedAt(new Date());

        publisher.publish(new NoteEditedEvent(this.note));

        repository.save(this.note);
    }
}

如您所见,NoteEditor 不是无状态的。

我想知道 NoteEditor 是 DDD 中的域服务吗?

我也想看看你的意见,为我的设计指正长大。

追加。 我解释了为什么要做有状态的编辑器。

我可以假设有两个客户端(WebClient 和 MobileClient)。

WebClient 将使用它,如下所示。

NoteEditor editor = noteService.getEditor(sessionUserId);
editor.open(selectedNote).setTitle(…).setContent(…).save();

MobileClient 将使用它,如下所示。

NoteEditor editor = noteService.getEditor(sessionUserId);
editor.open(selectedNote).setTitle(..).save();

这意味着某些客户端可以一次编辑一些属性。

因此,我想在open()方法中检查editable(authority),我想把修改信息放在save()方法中,比如上面的代码块。

以下是 NoteService 代码。

class NoteServiceImpl implements NoteService {
    ...
    NoteEditor getEditor(long userId) {

        User user = userRepository.findOne(userId);
        NoteEditor editor = new NoteEditor(context, user);
        return editor;
    }

    List<Note> getMyNotes(...) ...

}

【问题讨论】:

  • 你能解释一下为什么你让这个编辑器有状态吗?比如编辑器的客户端是什么样子的?
  • 感谢您的关注。我已经编辑了我的问题。
  • 恕我直言,编辑器的流畅api看起来不错,但直接实施启动会削弱好处。客户端对NoteEditorImpl和NoteEditor有很强的依赖,很难对客户端代码进行单元测试)。
  • 您的意见很好。实际上可以删除上下文参数。但我需要使用存储库和发布者。您是否建议也删除这些?我关心所有可能的事情。
  • And.. 有 NoteService 用于获取 NoteEditor。接口 NoteService { NoteEditor getEditor(long userId); // 获取编辑器以进行编辑或创建新的 ... } 所以.. 客户端不直接引用 NoteEditorImpl。客户端将通过 NoteService 获取 Editor。

标签: service domain-driven-design stateless stateful


【解决方案1】:

您的 NoteEditor 有两个职责。一种是编辑Note 对象,另一种是打开和保存Note 对象。如果将两者分开,一切都会很快到位。您需要一个用于打开和保存的 NoteRepository 以及一个用于流畅 API 的 NoteBuilder。 NoteBuilder 不是域对象,而只是一个帮助类,用于通过 fluent API 构建笔记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    相关资源
    最近更新 更多