可以在DDD(域驱动设计)中实现有状态域服务吗?

时间:2013-09-30 11:12:35

标签: service domain-driven-design stateless stateful

“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中的域名服务吗?

此外,我想看到你的意见,纠正我的设计成长。

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

我可以假设有两个客户端(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(...) ...

}

1 个答案:

答案 0 :(得分:3)

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