ドメイン駆動設計のお勉強1

最近id:ashigeruに影響されて、DDDを読み始めてみたりしてる。これが結構開ける世界があって、今までなんであんなに"機能"に拘って考えていたのか全くもって分からない。モデルを軸に置いて考えるとこうも色々としっくり来るとは思わなかった。しかも機能を先に考えないから、その機能がどうして必要なのか、欲しいその機能をスムーズに使ってもらうためにはどうすればいいのか、そんな事が比較的スムーズに考えられる。当然まだ勉強中なんで全然方向違いの事を言ってたりすることもあるんだろうけど、ちょっとずつブログに残していこうかなと思う(いつまで続くか分からないけど)

まず、モデルをベースに考えてて今日までちょっと勘違いしてたのが、保存先にあわせてモデルの実装を変えようなんて考えてた。例えばこんな感じ。

public interface UserProfile {
	void setName(Name name);
	void setPostalAddress(PostalAddress postalAddress);
	void setEMailAddress(EMailAddress emailAddress);
	void applyChanges();
}

で、階層としてはこんなイメージ。

  • UserProfile
    • RDBMSUserProfile
    • AppsUserProfile

要は、各実装の中で必要なリポジトリなんかを使ってそれぞれの保存先にapplyChangesメソッドで変更を反映、なんて考えてた。ただこれだとAppsに保存してあるデータをRDBNMS側に反映させる為には同じインターフェースを使ってるのに、モデルの変換を行わないとならない。だから、多分こうするといい。

public interface UserProfile {
	// setterは省略
	void applyChangesTo(Module module);
}

つまり実装の中ではこんな感じ。

@Override
public void applyChangesTo(Module module) {
	module.store(this);
}

ただ、これだとまた問題があって、両方にしまいたい場合には2度呼ばないとならない。んだからこうする。

public interface UserProfile {
	// setterは省略
	void addModule(Module module);
	void applyChanges();
}

で、実装が

@Override
public void applyChangesTo(Module module) {
	for(Module module : modules) {
		module.store(this);
	}
}

これでやっとこ一段落ってとこかな〜。で、これってよくあるaddHandlerとかと同じだよね。つーか、こんなこと学生の時でもやってたんだけど、なんでこうしなくなっちゃったのかね。変に分離を意識するあまり、機能単位に分けて、モデルにはロジックを置かないで・・・なんてやってたらこういった手法が酷く珍しいものになってしまっていた気がする。こうやって作ってあげれば、誰が何をするのかはモデルだけ見ればわかるし、モデルの切り分けを考える際にも誰がルートなのか、誰が子供なのかというのもわかりやすく考えられる。しかもモデルを使う人はどこにしまうかだけ分ってればよくて、どうやってしまうかは知る必要ないしね。

とまぁ、こんなしょーもないレベルのことをこれから思いついた時に連々と書いていってみようかな〜。