タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

実はDDDってしっくりこないんです

Sponsored link

DDD失敗パターン集

DDDという方法論それ自体に対する僕の立場はあんま好きじゃない寄りのフラット(といいつつほぼ忘れかけている)なんですが、過去何度もDDDでプロジェクトが爆死するのをみたり、爆破してしまったり……というのを見てきたので供養したいとおもいます。

メンバーの大半がDDDを知らない

「えっ!? ドメイン駆動を知らずにDDDを?」
「出来らぁっ!」

DDDを知らずにDDDをする、という前提がすでに禅問答じみてる気がしますが、たぶん一番よく見かける失敗パターンなんじゃあないでしょうか。
どういうことかというと、オニオンとかレイヤードとかクリーンなアーキテクチャのモジュールの命名ルールと構造を採用(採用できているとは言っていない)しただけの状態です。

私見ですが、アーキテクチャというのはメンバー全員がそれを理解できていない限り*1即破綻します。
理解できない人はどこに処理を書いていいのかわからず永遠にレビューでリジェクトされ続けるか、コピペでコードを増やすしかないからです。

DDDは導入もそうですが、初期の学習コストがかなり高いので多くの人がレイヤードアーキテクチャのValueObjectとかEntityとかRepositoryのサンプル実装だけ読んでなんとなくDDDを完全理解しており、ドメインの考察やモデリングはおざなりなので中盤フェーズでコードが破綻します。

かくいう私もうろ覚えでね。

CRUDの延長線上にあるBetter MVC止まり

「CRUDの延長線上」とはDBのテーブルがそのままコントローラーであり、1リソース単位であるという牧歌的世界観のことを指します。

Better MVCとしてのDDDは主に「Model View Controllerだけで切り分けるのしんどいけどEntityとかRepositoryとか層がたくさんあるからコード分割しやすい!」くらいの認識で採用されるものを指します。
この発想でコード分割をすると、実質的に密結合したものが分散配置されて処理が追いにくくなったり、バリデーションを追いにくくなったり、トランザクションが不可能になったり、なのにインターフェースがやたら分離されていてEnterprise FizzBuzz化していたり……

僕の短いキャリアでもDDDは定期的に流行ったり廃れたりしてるわけですが、ここ数年で散発的に発生しているDDDブームはRailsしんどいよねの流れから派生したものだと僕は考察しています。
ゆえに"Better MVC" (Betterとは?)というノリで設計されて夢破れたり、みたいなケースが……。歴史は繰り返す。

Javaの原典を直訳しがち

DDD自体は使用する言語に捉われない概念である、という主張には同意します。
しかし提唱され始めた時代や主に採用されていた分野の影響からなのかは知りませんが、存在するサンプルのほとんどはJavaです。
「言語が思考を規定する」のが真実かどうかは知りませんが、特定のプログラミング言語の慣習に固執するあまり他の言語の強みを活かせない人、というのは一定数*2存在します。

見落とされがちですがプロジェクトを考察してソフトウェアとして実装に落とし込む、というプロセスには当然選定された技術たちも含まれます。
Javaのために設計された構造がそのまま他の言語で適切かどうかについては一考の余地があるはずです。
Javaだから必要だった部分を省略したり、あるいはJavaだから必要なかった部分を補ったり、利用するライブラリのおかげで暗黙的に処理できる部分があったり。

例えばGoでDDDを採用するケースをここ数年でみかけるようになりましたが、愚直一歩手前をいくシンプルイズベストのGo言語の世界へエンタープライズ色の強いDDD系アーキテクチャを持ち込む場合はある程度の翻訳をかけるべきではないかと考えています。

同様に、この先日本でもサーバーサイドのTypeScript採用が増えていくと筆者は予想していますが、両者はclassやinterfaceなど同系統の構文を持つだけで実体もベストプラクティスも全く違います。なのでDDDを採用する場合にJavaの流儀を直訳するとおもわぬ地雷を踏むでしょう。
例えばValueObjectの実装は直訳してはいけません。

また、原典が書かれた時代からの変化もとりいれていかねばなりません。
TypeScriptでいうならば、JSONに型をつけられる特性やimmutabilityを重んじる最近の流行などを取り入れれば、より安全かつコンパクトな設計が可能になるでしょう。原点に固執するとその恩恵を受けることができません。特にimmutabilityを常に守ればいくつかの制約はそのまま陳腐化します。

ただのディレクトリとファイル名ルールとしての採用されたアーキテクチャ

DDD関連について学んでいるとEntityだとかAdapterだとかさまざまな用語が出てきますが、それぞれ一概念と一モジュールが常に対応するという思い込みは危険です。
そもそも適切なモジュールの粒度だとか、レイヤーの分離というものは単一の正解があるわけではなく、プロジェクトの規模や戦略によって変わるものです。

クリーンアーキテクチャの教義の一つに特定のフレームワークからの独立やレイヤーごと依存の分離といったものがありますが、雑に切って捨てれば象牙の塔建立の方法論みたいなもんだと僕はおもっています。
「フレームワークから独立して作られたアーキテクチャ」というのは実際にはただのオレオレフレームワークですし、レイヤーごとの依存が真の意味で消えることはありません(Interfaceで実装を分離して〜〜とかっていうのはただのJava実装上の方法論にすぎません)。

例えばGraphQLのAPIサーバーの設計をするにあたって、要件が十分にシンプルにまとまる見通しがあるのであれば僕はほぼ全てのロジックを各resolverに書き下して構わない*3と考えています。
乱暴なようですが、データの設計*4とユースケースの検討さえちゃんと行えばこのやり方でそこそこの複雑度をまかなうことは可能です。

ちなみに上記の主張をしている人間は僕以外に見かけたことがないので、実は安全かもしれません。

まとめ

こうして例をあげつらってみると、どれも有識者から「ドメインから駆動してへんだけやん」と一蹴されそうな雰囲気になっているわけなんですが、DDDが難解すぎること、そして適用するべきじゃない領域のサービス開発で用いられてしまっているというのが大きな原因として挙げられると僕はおもっています。

難解だとどう悪いかというと、難解すぎるせいで解釈が無数に派生していて議論が発散します。まずEntityってどのEntityのことなん?
また、ややこしいものが有名になるとキャッチーで表面的な比喩ばかりが注目を浴びてややこしいほうの本質はなおさらわけがわからなくなっていきます。これを「『シュレディンガーの猫』現象」といいます。
エンプラよりの「お堅い」アーキテクチャは人員のスケールのために存在する側面があるとおもうんですが、難解さはそこと対立する特性でもありますね。

適用すべきじゃない領域というのは、例えばリーンでウェッブなスタートアップとかです。
ドメインエキスパート……?お前がなるんだよ! といった開発と設計と仮説検証がイコールで結ばれているような極限環境でDDDするのはたぶん時間の無駄です。

ちなみに

DDDが述べていること、

  • ドメインにフォーカスしろ
  • ビジネスの専門家とかとうまく協業してドメインの探求をし続けろ
  • ちゃんとコミュニケーションして同じ単語を使え
  • 良いソフトウェアはドメインモデルを明快に表現しているんですよ

自体はめっっっっっっっっっちゃ大事だとおもいます。
が、DDDいわれんでもただの常識なのでは……?とおもわんでもないです。あるいは僕がただの常識だとおもえている今の大気を作ってきたのがDDDなのかもしれませんが、僕は歴が浅いのでよくわかりません。

かのリーナスもまずデータの設計をしっかりやれ、アルゴリズムをごちゃごちゃ弄るのは雑魚!!!って言ってた気がします。

ぶっちゃけていうと筆者はオレオレDDD実現系アーキテクチャが嫌いなだけなのかもしれません。
ていうかCQRSより複雑なアーキテクチャいらんくない?

お前間違ってるよ、って方はドシドシ教えてください。

以上!

この本ややこしすんぎ

hachibeechan.hateblo.jp

*1:仮に認識に齟齬があったとしても議論が発生するレベルの認知度

*2:大多数の誤字です

*3:人類として最低限度の節度は保つべきですが

*4:RDBのテーブル構造と一対一対応させるようなお粗末なものは設計とは呼びません