Entityとして「Note」Domainオブジェクトがあります。
@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 の Domain Service なのだろうか?
また、あなたの意見、私のデザインの修正が成長するのを見たいです。
追加します。ステートフル エディターを作成した理由を説明します。
2 つのクライアント (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(...) ...
}