PHPのArrayに苦しんだ結果、LaravelのCollectionだけ導入した話 | learningBOX Engineer Blog
みなさん、初めましてlearningBOX株式会社の開発部開発課に所属している末廣と申します。突然ですが、みなさんはPHPのArrayは好きでしょうか。私は嫌いです(ドン)Arrayが嫌いな理由...
https://www.wantedly.com/companies/learningbox/post_articles/538571
learningBOX株式会社の開発部開発課に所属している末廣です。
前回はLaravel Collectionを導入した話をしました。
今回はlearningBOX開発にDDD(ドメイン駆動設計)を導入した話をしたいと思います。
まず、ドメイン駆動設計について簡単に説明させていただきます。
ドメイン駆動設計(DDD)は、ソフトウェアの設計手法の一つで、特に複雑なビジネス要件を持つソフトウェアシステムに対して有効な手法です。
DDDの主な目的は、ビジネスの問題領域(ドメイン)を理解し、その知識をソフトウェア設計に反映させることです。これにより、ビジネスの要件とソフトウェアの設計が密接に連携し、ビジネスの要件が変更された場合でもソフトウェアが柔軟に対応できるようになります。
DDDの中心的な概念は、ドメインとモデルです。ドメインはビジネスの活動やビジネスが対処する問題領域を指し、モデルはそのドメインを抽象化したもので、ソフトウェアの設計と実装の基礎となります。
DDDでは、モデルは常にビジネスの要求と一致するように保たれ、ビジネスの専門家と開発者が共有する共通の言語(ユビキタス言語)を通じて表現されます。これにより、ソフトウェアがビジネスの要求を正確に反映し、ビジネスの価値を最大化することが可能となります。
まとめると、ソフトウェアの機能性と保守性を高い次元で両立することが可能な手法で、アジャイル開発とも相性が良いとされています。
DDDに興味を持ったきっかけは2023年の1月に遡ります。
当時、私が所属していた開発チームのプロジェクトマネージャーから「どうもDDDが良さそうと聞いたので、次の開発はDDDでやってみたい」と言われたのが最初でした。
この時は「DDDなんてよく知らないけど、TDD(テスト駆動開発)の亜種でしょ?」と、とても軽い感じで考えていて「いいんじゃないですか?やってみましょう。」と回答しました。
この時点ではプロジェクトマネージャーも私もDDDがどういうものかわかっておらず、複雑な要件を解消できるプラクティスの1つくらいにしか思っていなかったのですが、DDDについて調べれば調べるほどとても難易度が高く、一朝一夕で理解できるものではないというのがわかって来ました。
この時は次の開発が始まるまでの期間が短かったので、DDDで開発することは見送ることにしました。
しかし私はこの時にDDDに触れて、複雑かつ頻繁に変わるビジネス要件に継続して対応できる優れた手法ということがわかって、すっかりDDDの虜になっていました。
そして、DDDの中でもモデリングまで行う重量DDDと、DDD的な思想とアーキテクチャだけを採用する軽量DDDというものもあるということも知りました。
軽量DDDであればボトムアップでのチーム内だけの取り組みでもいけそうだなと思い、まずは軽量DDDから取り入れることを、自分の中の目標にしました。
そこからしばらくして、DDDを導入するプロジェクトを立ち上げることにしました。
DDDを導入するといっても社内に経験者が居るわけではなかったので、まずはDDDについて改めて最初から勉強しようと思い、書籍やテックブログを読むことにしました。
その中でいくつかキーになるものがありましたので、ご紹介します。
エリック・エヴァンスのドメイン駆動設計
いわゆる、ドメイン駆動設計の原典です。
内容は非常に重厚で網羅的に学ぶことができますが、抽象度が高くDDD未経験者がそのまま実践するのは難しく感じました。
個人的に、初心者が最初に読む書籍としてはオススメできません。
そこで別の書籍などで知識の補完を行いました。
個人的に1番良かったのは、little-hands(松岡幸一郎)さんの「ドメイン駆動設計 モデリング/実装ガイド」「ドメイン駆動設計 サンプルコード&FAQ」です。
DDDについて積極的に発信されている方で、DDD導入コンサルなどもされているそうです。
ブログも参考になります。
boothでしか購入することができないのが難点ですが、ドメイン駆動設計が100ページ程度に凝縮されているので、入門用としては非常に読みやすいです。
エヴァンス本と違い具体的な内容で、モデリングのやり方についても紹介されています。
ミノ駆動さんの「良いコード/悪いコードで学ぶ設計入門」や、Qiitaの記事も参考になります。
書籍ではDDDという用語にはほとんど触れずに、エッセンスを取り入れて紹介されています。
内容的には軽量DDDにあたると思います。
DDDを導入すると言ってもバックエンドエンジニアを中心に影響がある話なので、勝手にやるわけにはいきません。
次にやるべきことは、社内向けに提案をしてCTO(弊社の場合は代表の西村が兼任)やチームリーダーに合意を得ることです。
Googleドキュメントを使って、提案資料を作成して展開しました。
以下のような内容をプレゼン資料に盛り込みました。
MVCアーキテクチャよりも実装時のコストは上がるため、保守コストや変更容易性などを持ち出して、そこのフォローも意識しました。
上記の資料を元に社内提案したところ良い返事が貰えたので、つぎは協力者を探しへと移ります。
1人で進めずに協力者を求めたのには2つ理由があります。
ひとつは、DDDは難易度が高く1人で進めるのが難しいと思ったから
もうひとつは、DDD自体に定型的な手法が存在しないため、1人で決めることで個人の主観が反映されてしまうことを避けるためでした。
幅広い知識を持っている当時のバックエンドチームリーダー、個人的にDDDを勉強していた若手エースバックエンドエンジニアに協力を依頼したところ、快く引き受けてくれました。
今から考えると、この人選がプロジェクトの成否が左右していたと思えるほど大事なものでした。
とても良いメンバーの選出ができたと思っています。
最後にタイトルにもあるモダンフレームワークを採用していないのにDDDを導入しようと思った理由を説明します。
learningBOXのバックエンドはPHPで書かれており、フレームワークは内製のフレームワークを採用しています。
フレームワークが備えている機能としてはいたってシンプルで、ルーティング・権限・ロギングがあるのみといった感じです。
モダンフレームワークが備えているようなコレクションやORMといった機能は存在しません。
コレクションに関しては前回の記事「PHPのarrayに苦しんだ結果、LaravelのCollectionだけ導入した話」で導入済み
過去にモダンフレームワークへ乗り換える話も出たようですが、様々な障害(主にコスト面)があり実現には至りませんでした。
そんな中モダンフレームワークへの乗り換えではなく、DDDを導入しようと思ったのにはいくつかの理由があります。
・複雑な機能要件に対するMVCアーキテクチャの限界(Fat Model)
learningBOXのユーザーに対してかなり細かく複数の権限の設定を行える、ユーザーが所属するグループも入れ子状にできる、様々な形式の教材を扱うプラットフォームである仕組み上、どうしてもバックエンドが複雑化してしまいMVCアーキテクチャのFat Model化に苦しんでいました。
・スモールスタートが可能である点
フレームワークの換装は、今までのプロダクトコードが全て対象になり、長期運営してきて肥大化したプロダクトへの導入は膨大な工数がかかります。
その点DDDの導入というのは新たにディレクトリを切り、その中でのみ有効なルールを策定することで、現状のプロダクトコードに影響を与えることなくミニマムに導入することが可能です。
これらの点からまずは軽量DDDから導入して小さく初めていこうという考えに至りました。
今回の記事ではDDD導入プロジェクト立ち上げまでを説明させていただきました。
実際にプロジェクトをどのように進めたかという部分と、最終的にどのような形になったかは、後編で説明させていただきます。