はじめに
DDD(Domain Driven Design、ドメイン駆動設計)の学習は、とても難しいと思っています。多くの人が、DDDというのがあるらしい、と勉強を始めては挫折していったと思います。自分もそうでした。ある程度もがいてDDDの本を読んだりTwitterを追ったり自分で設計してみたりして、結局、自分がどのようなところに落ち着いたのか、などを書いてみたいと思います。下記の多くは自身の感想であり、主観を大いに含みます。
なぜ、難しいか
- 基本的に抽象的なことを扱っている上に、前提や語彙の定義があいまいなこと
- 歴史が浅いこと
- 具体例を表に書きづらいこと
が原因だと思います。
基本的に抽象的なことを扱っている上に、前提や語彙の定義があいまい
まず、数学のように厳密な語彙の定義がありません。もちろん数学ではないので当たり前なのですが、そもそも抽象的な話をするならせめて厳密に定義して欲しいものです。
歴史が浅いこと
DDDという名前を作った、ドメイン駆動設計というエリックエバンスの書いた本自体が出版されたのは2003年のことなので20年も昔ですが、日本でここまで最近よく聞くようになったのはここ5,6年程度だと思います。歴史が浅いと、事例や注意点、言い換えや具体例などのあらゆる理解の糧となるリソースが減るため、理解しづらいです。
具体例を公に書きづらいこと
複雑なプログラムをわかりやすく書くための手法であり、そもそも何かしらの複雑な文脈をもった上で機能しているプログラムに対して効果的に綺麗にかけるというのがDDDです。となると、何かしら説明するにはその「何かしらの複雑な文脈を持った上で機能しているプログラム」を用意してそれを綺麗に設計する、という手法をとることになるわけですが、だいたいそういったものは会社の中にあるものであり、インターネットに公開して書けるものではありません。具体例を公に書きづらいため、前提が異なるまま議論せざるを得ず、非常に理解しづらくなっていると感じます。
DDDの落ち着き方
1. 技術や用語、概念などから、一部だけ盗む
ValueObject、Repository、Dependency Injection、テスタビリティ、ユビキタス言語、などの概念や用語だけを盗みます。
例えば、永続化するわけではなく各テーブルにamountと単位および単位に関する計算ロジックがあるなら、それを1つのドメインモデルとしてValueObjectの形でAmountモデルを作って、そこに集約させたら扱いやすいかも知れません。どうもamountに関するロジックが散らばっているが、直し方がいまいち分からないし、大勢が参加するPJだといちいち語彙の統制が取れないという時に、ValueObjectとしてAmountモデル¥を利用したらいいなと気づくことができます。
FileやIO、外部API、DBやRedis、別プロセスといった外部への通信は、だいたいレポジトリ層にまとめておくと、依存性の注入によりテスタビリティを上げられるでしょう。一旦それでいいと考えます。
気づいたら、エンジニア、営業、PM、ユーザ、社内のadminユーザ、などがそれぞれ同じことを別のワードで話したり、同じワードで違うことを指したりして話していたら、ユビキタス言語がないんだなとすぐ気づけます。こういう時は、DDDの本を読んで得たユビキタス言語で会話することを徹底する、だけでまずとても日々のコミュニケーションが楽になり、システムに対する理解がエンジニア同士でも深まったりしてよいです。この、プログラムとビズの使う用語を一致させた方が良いということは、DDDを勉強していなければ確信を持って主張することはできなかったはずです。
他も同様です。
2. 深入りしすぎない
これはエンジニアとしてあるまじきかもしれませんが、あえて主語を大きく抽象的に書きます。なお、前提としてスタートアップを主に念頭にして書きます。
最低限のクオリティの機能があれば、そのプログラムが金を産むかの8割くらいはビジネス領域で決まる印象です。理由は、金を産むプログラムになるかは概ね、事業の時期と何を作るか?などプログラム外の要素で決まるからです。ビズサイドが、基本的にwhatを決め、プログラムは概ねhowの領域担当になります。なので会社員エンジニアとしては、まずはDDDより優先すべきもの、すなわち機能のリリースがあるはずです。
別にMVCレイヤになっておらず、Cに全て詰まっていても、レガシーな言語、フレームワーク、見るに耐えない汚い設計でも、そのプログラムで多くのお金を稼ぐ会社を見てきました。一方で、非常に綺麗なコードだけど、汚いコードの1%も稼げない会社も見てきました。確かにエンジニアリングとビズの働きは両輪ではありますが、よほどテックドリブンな会社でない限り、丁寧なエンジニアリングでない稚拙な技術であっても事業成長の方が大事で、そのために汚いコードの方がむしろ短期的に出力が出るなら、全体最適を見たらそちらの方が良いこともあります。なんなら、最初から綺麗なコードを書く会社ほど(初速が出にくいため)潰れやすいのではないか?という個人的仮説まであります。
ただし、一方で稚拙なエンジニアリングにより急成長したものの、成長が急に鈍化する企業も見たことがあります。なので、常に汚いコードを書いているが、あくまで worse is better のフェーズだからそういうコードを書いているのであって、隙あらば本来リファクタリングしないといけないのだという意識を忘れてはいけないのだと思います。そうでないと、状況が変わったのにも関わらず方向転換できずに汚いコードに汚いコードを上塗りして、どこにコードを足したり引いたりしても、バグを起こして壊れてしまう、そのようなものが出来上がり、ゆるやかに死を迎えるのだと思います。