DDDが難しいって話なんじゃけど...
DDDの入門でつまづくって話
なんか思う事があったのだ書いた。
DDDのサンプルコードのリンク集だとおもってみてもらうのがいいかも。
— ぷなつしー@サイドPJもやる個人事業主 (@Pooh3Mobi) 2017年9月24日
DIが前提で難しいん?
ヘキサゴナルアーキテクチャみたいなものを使うとDIPの概念とDIの導入の検討が必要になるという話で、DDDの思想には関係ない。
それでもDIが知りたい場合は次の項へ。DDDの話のみでいいなら飛ばしてね。
それでDIってなんなん?
DI自体は単純に依存関係をJavaのインターフェイスみたいなもので、実装と抽象を分離するって話。
たとえばサーバー側がまだ用意できてないみたいな状況でもMockクラスで置き換え可能にしておいて、Stubなデータを返す実装で簡単な通信回りの単体テストができるようにしたいとか,Javaのクラスベースで実装の置き換えを可能にしておくとか、そんなイメージで良いと思う。
実際にそれを使う事はテストコード書く時が一番使う。
単体テスト時、サーバーが準備されていないけどJsonのフォーマットだけ決まっている時とか。new Foo(new BarMock())としているところがnew Foo(new BarImpl())みたいに簡単にスイッチできるのって楽だよねとかいうのはほとんど幻想だってこと。
DIコンテナを知ったかぶってみる
DIすると必ずDIコンテナの話が出てくる。多分何かPHPとかのフレームワークに依存した話だったりしそうだけど、一部で好例が出てなんとなく広がっていったけど、DIコンテナありきで話す人が多いので、初心者がくじける罠になっているっぽい。
簡単にいうとDIPな実装をしようとするとDIって実装の考え方が大事になってくる(DDDとDIPは別モノ)。DIをしようとすると、Javaだとクラスの実装時にコンストラクタで最初に依存関係のある実装を持ったクラスのインスタンスを引数で取り込むって感じのコードになる。これを属に?マニュアルDIって言うらしい。それをやって行くとプログラムが複雑になったときに、依存関係が多重になっていくと、マニュアルDIしてるコードが見づらくなる。この依存関係だけをまとめた書き方と、実際にJavaだとpublic Foo provideFoo(){new Foo(new Bar(Baz.getInsatnce(), new Qux()), new Quux()));}みたいなコードになったりする部分がなくなってスッキリするって話。DIコンテナそんなにがっつり触ったことないけどwあとDIコンテナによっては依存関係が見やすくなるし、マニュアルDIを採用してて間違って依存関係のあるクラスのインスタンスの参照子にNullをつっこんでたって話も実際にあったので。フェイルセーフとして導入はアリなんじゃなかろうか?
前はマニュアルDIでよくね?って思ってた。
エリックエバンス本が分かり難い?
どうでもいいことに時間費やしてすみません。こちらが本記事の本題です。
正直僕も、エリックエバンス氏の本を読んで一発で解った!みたいな状況にはならなかった。いわゆるIDDD本も買ったけどわからなかった。
というか最初から理解する必要がそこまでない事が途中でわかった。後で説明するけど最初にざっと全体像がつかめてわからないものが見えてきたら、後はコードを書いて必要になったら読むというスタイルで良いのだという事に気が付いた。
実際僕は、Android界隈で有名な?DDDの薄い本を買っていないので知らないけど。僕がある程度IDDD本なりエリックエバンス氏のDDD本を読んだときに出会ったPDFが役にたったので、DDD勉強はじめて迷走している方はこちら
Domain Driven Design(ドメイン駆動設計) Quickly 日本語版
を個人的にお勧めする。これはInfoQが独自にまとめたPDFの記事らしい。そして、ここにあるエリックエバンス氏とのインタビュー記事が一番の"目からうろこ"だった。どうやらコードがあるらしい。僕が知っているDDDを話す人はこのPDFもエリックエバンス氏のインタビューにも、氏のコードにもフォーカスしていないのが不思議なのだが何故だろうか?その方が単に知らないだけなら、それで公演なりしてて稼いでいる話も聞くのでお粗末なきがする。と個人的な遠回りさせられた私怨や違和感はどうでもいいか?エリックエバンス氏は言っている。”本とコードを読んで”と。
それで、どこにそのコードがあるかっていうと
こちら。で他にもいろいろ有志の方がサンプルコードを作ってくれているっぽい事もわかった。
エリックエバンス氏の本を元に作られたのがこちららしい。
IDDD(実践ドメイン駆動設計)本をもとにつくられたのがこちららしい。
本+コード
僕たちは結局何が抜けているのかなんて想像しないのだろうか?コードが欲しいのにコードがないみたいに思った時期があった。こんだけ有名な考え方なら例になるコードだってあるはずと考えるべきではなかったか?
僕たちは新しい概念を学んでも、それがコードとしてどういう意味をもつのか?複雑なのかそうでないのか?といったところから入らないと難しいのにそれを忘れて何を議論しているんだろう。
必要になったら読む
僕はこれが最強だと思ってる。理由はDDDはコードを書こうとしないと実際なんなのかわからないと思うから。実際論より証拠というか、実装だ。実践でやってみない事には始まらない。なんで境界付けられたコンテキストのマッピングが必要なのかってわかりはしない。だれかの説明を聞いても、なんとなくわかった気になるだけがせいぜいなのだ。そんなもので解りはしない。実際に生きた意味のあるコードに書いてみて、最初はどんなクラスが必要になるんだっけ?ってエリックエバンス氏の本を開くのだ。そしたら誰が中途半端な事を言っているのかわかるようになる。
画竜点睛というか蛇足
僕が思うDDDの一番の利点は、コードが一貫性を持つようになる事だ。表明コード、Entity、ValueObject、DomainServiceやDomainEventをProcess(Saga)、Repository、Facadeがあるだけで、これらがどのようなものなのか?がドメインにあるビジネスロジックに見事につながるようになる。この爽快感がDDDの一番のポイントではないかと思う。誰が書いてもだいたいこのクラス群があるだけで安心するのだ。そしてデザインパターンに習熟するより容易い。これは面白い事だと思う。なので僕はDDDを他人にも勧めるようにしてる。
終わりに
本当はCleanアーキテクチャにDDDを注ぎ込んでもOK。あとEntityは変更前提だけどあんまり露出しないように。って話をしようとしてAndroidCleanArchitectureのコードを例にしようとしたけど…面倒だったので上のサンプルコードをしっかり見た後、AndroidCleanArchitectureのEntityをmapperで変換するあたりを見てください。最後に念押し"コード読もう"
ほぃじゃーねー。
追記
Qiitaにポエムをそぎ落としたリンク集として書いておいた。 ドメイン駆動設計入門でくじけないためのリンク集(サンプルコードのリンクあり) - Qiita