社内DDD勉強会を経てトライしたこと6つ

ブログアイキャッチ | 社内DDD勉強会を経てトライしたこと6つ

こんにちは、プレックスの石塚です。

今回のブログでは弊社で行っているエンジニアの社内勉強会と、その中での学習をベースに業務中でトライしたことを6つ紹介させていただきます。

エンジニアの社内勉強会について

プレックスでは週1の頻度でエンジニアの勉強会をやっています。 テーマは社内で使っている技術やこれから導入を予定している技術など、ある程度の共通認識はありますが、比較的自由としていて、雑談ベースでカジュアルに決めています。

勉強会の形式はその時々で変わりますが、多いのは輪読会で、各自事前に書籍を読んできてもらい、勉強会当日にGoogle Jamboardに書籍を読んでの学びや気付き、わからなかった点、深堀りした点などを記載して、共有・議論していくスタイルです。

プレックスのエンジニア勉強会
実際の勉強会時の資料

DDD勉強会について

初回の勉強会のテーマとして選んだのがドメイン駆動設計 モデリング/実装ガイドの輪読会でした(今はプログラミング TypeScriptの輪読会を実施しています)。

DDDをテーマに選んだ理由は以下の2点です。

  • 弊社のプロダクト開発において、事業間の連携が存在し、複雑なドメイン知識を必要とする
  • 新しいメンバーがジョインしてドメイン知識の共有に課題があった

トライしたこと

次に今回の記事の本題である、勉強会を経てトライしたことを簡単に6つ紹介していきます。

実装面以外でのトライ

ユビキタス言語を作ってみた

ユビキタス言語はDDDに登場する概念の1つで、チームが共通で使用するための辞書や用語集のようなものです。 恥ずかしながらユビキタス言語はトライしてみたものの、今は廃止してしまった事例です。

ドメイン知識を言語化して共有したいという導入の背景があったのですが、ユビキタス言語に落とし込もうとすると単語の形で表現しなくてはならないので、細かい情報の伝達には向いておらず、後述するドメインモデル図の方がマッチするということで廃止しました。

ドメインモデル図を書く

ドメインモデル図はテキストの手法をそのまま踏襲しているのですが、Notion上で

  • 簡易なER図を書く
    • Mermaidを使用
  • テキストでドメイン知識を書く

といった簡単なものです。 ドメイン知識を言語化して共有したいという目的では、細かい情報もテキストとして残せるのでユビキタス言語よりもドメインモデル図の方が適していました。

簡略化したドメインモデル図の例
簡略化したドメインモデル図の例

また特定のモデルだけ作成することもできるので、新規作成するモデルから始められるなどの導入のしやすさもありました。 弊社もすべてのモデルをドメインモデル図化するのはやり過ぎだと思い、重要なモデルだけドメインモデル図に残しています。

ドメインモデル図によって、ドメイン知識の共有が楽になり、テーブル名やカラム名のレビューがしやすくなりました。 またこの勉強会を機会にドメインモデル図以外にも、手動オペレーションの実行方法をまとめたりと、ドキュメント化が捗りました。

実装面でのトライ

弊社が Ruby on Railsgraphql-ruby を使ってバックエンドを開発しているので、その2つの技術に関連した内容が多いですが、実装面でトライした内容をご紹介します。

テスト方針の共通認識を揃えた

ちょうど勉強会を始める2ヶ月ほど前にテストが全くない状態からモデルのユニットテストを書いていくという方針を決めました。 ただ実装者によって、モデルの責務が曖昧になっていたり、どこのモデルで処理を行うかにばらつきがあり、テストのカバレッジも中々上がっていきませんでした。

DDDでは変更に強いソフトウェアを作るという大目的があり、それを実現するために各レイヤーの責務を明確にしたり、テスタビリティを向上させるための方法があります。 自分たちもテキストを参考にしながら、現状のアーキテクチャーや実装と照らし合わせて、以下のようなテスト方針に対する認識を揃えていきました。

  • 各レイヤーの責務を明確にし、モデルが担うべき処理はクラスメソッドやインスタンスメソッドに積極的に切り出す
  • 整合性を保つために、集約ルートから集約単位でトランザクションを掛けて更新処理を行う
  • モデル層の変更をしやすくするため、コントローラー層でもテストを実施する

勉強会を進めていく中で自然とこのような共通認識が揃っていき、テスト導入も一気に進んでいきました。

名前空間を分割する

DDDには境界づけられたコンテキストという概念があります。説明が難しいですが一言でまとめると、モデルの適用範囲を業務ドメインやチーム単位の境界で分割していくといったものです。

書籍の中では1コンテキスト1アプリケーションのマイクロサービスが推奨されていましたが、それを実現するためには実装コストが高く、中々導入できるプロダクトは少ないのではないでしょうか。

一方で1コンテキストで複数アプリケーションを扱うためにパッケージを分割する手法も紹介されており、弊社でも部分的にRubyのmoduleを使って名前空間を分割していくことを実施しました。 Ruby on Railsを使っているので、モデルは共通化した方がメリットを享受しやすかったため、コントローラーなどを中心にユーザーの種類単位で分割していきました。

enumによるドメイン知識の表現

書籍の中でドメイン層でのドメイン知識の表現方法として、enumを積極的に使うことが紹介されていました。

ActiveRecord::Enum の存在は知っていたのですが、テーブルのカラム型を整数にする必要があると思いこんでいたため、DBのレコードを直接見たときの視認性が下がってしまうという理由で個人的に使いたくないと思っていました。 しかし調べてみると、文字列型でもenumを使用することができたため、導入することを決めました。

stackoverflow.com

各レイヤーでの責務を明確にする

DDDの中では各レイヤーの責務を明確にして処理を分割するという考え方があります。 新規事業においては、開発のスピードが求められたり、今後使われるかどうかについての不確実性が高い開発を行うことが多いため、トレードオフを意識しながら開発を進めることになると思います。

自分たちも大まかな設計やディレクトリ構成などはRailsのデフォルトのMVCのまま変更しませんでしたが、部分的に取り入れられる箇所はいくつか試してみました。 具体的には

  • コントローラーでGraphQLのオブジェクトを to_h で変換し、モデルでは直接使わないようにする
  • GraphQLのDirectiveを使用してプレゼンテーション層の処理を切り出す

などを実施しました。特に1つ目の変更ではテストデータの用意が簡単になり、テストしやすさの向上を実感できました。

おわりに

個人的に勉強会をやっていてよかったなと感じることの1つが各自の抱えている課題や理想の認識をすり合わせることができる点で、そこが業務上のトライにも繋がりやすかったのではないかと思います。

今後も勉強会を続ける上では、インプットとアウトプットのバランスを大事にしていきたいです。

最後に、プレックスではソフトウェアエンジニアフロントエンドエンジニアを募集しています。少しでも興味を持っていただけた方は業務委託や副業からでも、ぜひご応募いただけると幸いです。

dev.plex.co.jp