ドメイン駆動設計でなぜ作るか、どう作るか

Shinichiro Nogami
Aerial Partners
Published in
Jul 6, 2021

こんにちは、Aerial Partnersの野上です。Aerial Partnersでは、会計やブロックチェーンといった領域でのソリューションを提供しています。現在は新規事業開発を行うチームに所属し、ドメイン駆動設計(DDD)とGo言語を採用したソフトウェアを開発しています。

開発する中で、社内でドメイン駆動設計についての知見もたまってきたので、それについてまとめてみたいと思います。

ドメイン駆動設計でなぜ作るか

ビジネスロジックのための指針

DDDを採用するメリットとして大きいのは、ソフトウェアのビジネスロジックを書くための指針をチームで共有できると言う点が大きいと考えています。

ソフトウェアにおいて、設計方針の統一性というのは非常に重要な問題です。統一性のあるソフトウェアでは、どこに何が書かれているのかがすぐわかりますし、保守性の面で非常に優れたものとなります。たとえ優秀なエンジニアが揃っていたとしても、 指針なくみんなが思い思いに実装してしまえば、統一性のないものになってしまいます。

なので、良いソフトウェアを作るには指針(きめ)が必要です。もちろんそれを自前で作って運用してもいいのですが、ドメイン駆動設計という完成度の高い指針を活用することで、ソフトウェアに統一性をもたせ、生産性を高めることができます。

Webフレームワークとの比較

ここでは、DDDがどういうものかイメージをつかむために、Webフレームワークと比較をしてみます。Ruby On Railsなどに代表されるWebフレームワークも、「設定より規約」という理念を持っているように、開発における指針を提供してくれるツールです。では、これらはDDDの指針とはどう違うのでしょうか。

フレームワークは、Webルーティングやコントローラ、ORMなどの扱い方について指針をあたえてくれるものですが、ビジネスロジックについての指針があるわけではありません。ビジネスロジックはエンジニアの裁量に任せ、それ以外の指針を提供するものになります。

ビジネスロジックに対する指針がないため、よくRuby On Railsのプロジェクトでは、ビジネスロジックがサービス層とモデル層に何の指針もなく混在していたり、またデータベース層のロジックとビジネスロジックが混在してしまったりといったことが起こりがちです。これらは可読性・保守性を大きく損ねてしまいます。

そこで、フレームワークが提供していないビジネスロジックの指針にDDDを用いることで、より保守性の高いアプリケーションを開発することができます。

ドメイン駆動設計でどう作るか

こちらのパートでは、DDDを実践するためにどのような言語やフレームワーク、アーキテクチャを使うべきかについての私見を述べます。

プログラミング言語

言語は型がある方が好ましいです。

ドメインを設計する時に多くのクラスを作るため、この変数やプロパティがどの型なのか?ということが分かる状態であることが望ましいです。

AerialチームではGo言語を選択しましたが、Rubyなども、漸進的型付けを採用し始めています。型の機能が充実している言語であれば問題ないでしょう。

ORM

あまりドメイン駆動本でORMについては触れられていないのですが、使いやすいORMを採用することは、DDDで開発する上で生産性に大きく関わるところだと考えています。

ドメイン駆動設計では、ドメイン層で生成したドメインオブジェクトをレポジトリ層に渡したり、レポジトリ層で生成したDTO(私たちのチームではORMで用いるオブジェクトをこう名前づけしています)をドメイン層に渡したりといったことを頻繁に行います。

ドメインオブジェクトをレポジトリ層に渡す時は、集約単位で渡すという決まりがDDDにはあります。集約単位のオブジェクトは、1対多の関連をもったオブジェクトの集合である場合も多く、アソシエーションされたDTOをそのままDBに保存できる機能がORMにないと、非常に不便を強いられることになります。

私たちのチームではORMにGormを使っているのですが、このアソシエーション周りの対応が結構クセがあって使いづらく、毎回ちゃんと保存されてるか検証しながら進めなければいけないので、なかなか困っています。一方、Railsで使われているActive Recordはこの辺りが非常に使いやすいので、個人的にはRailsでDDD開発するのは結構相性が良いのではないかと思っており、次機会があれば試してみたいと考えています。

GraphQL

GraphQLもDDDと相性が良いです。単純なAPIの場合、GraphQLで定義するスキーマは、DDDにおけるドメインをそのまま利用できることが多いです。例えば、Userを1件取得するというAPIの場合、UserドメインクラスをそのままGraphQLのスキーマとして定義し、それをAPIで返すということもできます。また、Goのライブラリのgqlgenでは、スキーマをstructから生成することもできます。

まとめ

ドメイン駆動設計を用いることで、チームの中での設計に対する共通認識ができるとともに、ドメインクラスを中心に汎用的な設計に基づくソフトウェア開発を行うことができるようになりました。

また、今回は触れませんでしたが、ドメイン駆動設計を用いてビジネス側の人たちともコミュニケーションをとりやすくすることができます。チーム開発を円滑に行うための非常に強力な武器になると実感しているので、今後も学習を続けていきたいなと思います。

--

--

Shinichiro Nogami
Aerial Partners

灘高等学校、慶応義塾大学卒。 卒業後、大手SIerや、DeNA、スタートアップなどでエンジニアの経験を積む。 2018年1月より株式会社Aerial Partnersにジョインし、Gtaxのサービス開発にリードエンジニアとして携わっている。