本日のお裾分け

日々の開発で得た知識をシェアします。Java/Scala/Ruby/javascript

DDDことドメイン駆動設計(Domain-Driven Design)の主要概念(前編)

ドメイン駆動設計、はじめました。

テキストはこちら。

実践ドメイン駆動設計 Ch.1 DDDへの誘い

DDDって何ですか?

ドメイン駆動設計(Domain-Driven Design 略してDDD)とは、
品質の高いソフトウェアを開発するための設計手法です。

DDDで得られるメリット

  • 可読性の高いコードが書けます。
    • DDDでは業務(現実)の振る舞いを、ソフトウェア(コード)で表現する手助けをします。
      その結果、他人から見ても可読性の高い、かつ業務要件が表現されたコードがかける様になります。
  • 戦略的にソフトウェアを成長させることができます。
    • コードの可読性が高まることによって、改修の難易度を下げることができます。 oo機能にxxを追加したい、yyの仕様は修正したい、という顧客の要望に応えやすくなります。

めっちゃ重要やん!!!

話し足りない気もしますが、 今日は大枠を説明するので、内容を聞いてどういったものか理解して頂ければと。

今から話すことと話さないこと

話すこと

  • DDDの主要な概念
  • DDDで設計するやり方(大枠)

話さないこと

  • DDDで利用するオブジェクトのパターン
  • DDDの主要概念の実務での活用方法

DDDの主要概念

  1. ドメインエキスパート
  2. ドメインモデル貧血症
  3. ユビキタス言語

主要概念1.ドメインエキスパート

業務フローについて、よく理解してる人

業務知識に長けた人かもしれないし、プロダクトの設計をした人かもしれない。 もしかしたら、営業担当者の中にいるかもしれません。
役職は関係ありません。
とにかく、その業務で最も大切なところを一番よく知っている人がドメインエキスパートです。

この人のメンタルモデルをソフトウェアに反映することが、DDDの目標となります。

自分のPJTで考えると・・・? 身の回りののドメインエキスパートは誰か?
ここまでは本に書いてある内容でしたが、ここは個人的な意見です。

ドメインエキスパートが「業務の流れ」を理解している人だとすると、
「システムを使って業務を効率良くこなし、事業価値に結び付けられる人」
だと私は考えます。

ざっくり言うと「システムを使いこなしてる人」。

「システムを使って」という点がミソで、
お客さんの担当者にはいないこともあると思いました。
つまり、ただ、機能を使ってる人ではなく、機能を使って事業価値に結びつける方法を知っている人ではないかと思います。

導入・保守をやってる人こそドメインエキスパートなんじゃないかと。
設計・開発に関わる人は皆、目指したいところですね!精進します。。。

主要概念2.ドメインモデル貧血症

こちらは、具体例で説明します。

ドメインエキスパートのメンタルモデルを設計に落とし込むことがDDDの目的と言いましたが、
今から見せる2つのコード、どちらが業務での使われ方がイメージできますか?

public class CustomerSaveService{

    public void saveCustomer(
        String id,
        String name,
        String address,
        String phoneNumber){

            Customer customer = customerDao.findById(id);

            if(customer == null){
                customer = new Customer();
                customer.setId(id);
            }

            if(name != null){
                customer.setName(name);
            }

            if(address != null){
                customer.setAddress(address);
            }

            if(phoneNumber != null){
                customer.setPhoneNumber(phoneNumber);
            }

            customerDao.saveCustomer(customer);
    }
}

次。

public CustomerService{
    public void changeCustomerName(
        String id,
        Stirng name){

            Customer customer = customerRepository.findById(id);


            if(customer == null){
                throw new IllegalStateException("CUstomer doesn't exist.");
            }

            customer.changeName(name);
    }
}

public interface Customer{
    public void changeName(String name);
    public void relocateTo(Address changedAddress);
    public void changePhoneNumber(PhoneNumber number);
    public void disconnectPhone();
}

getter, setterまみれのコードはこの本でボロクソにdisられるのですが、
そうなってしまった一因にVBや初期のHibernateでgetter, setterを定義させたがっていたという背景があると書かれています。

とはいえ、getter, setterまみれのコードの問題点は3点あり、

  • CustomerSaveService#saveCustomer()に作成した意図が反映されていないこと。
  • 実装自体が、不要に複雑になっていること。
  • ドメインを表すはずのCustomerクラスがが、ただのデータ置き場となってしまっていること。

があります。

こうなると、コードを読むだけでは意図が読み取れず、
毎度、ドメインエキスパートに確認をする必要が出てきてしまいます。

まとめると、
なぜこのコードが業務の役に立つのか?が読み取れない設計のことを  ドメインモデル貧血症
といいます。

主要概念3.ユビキタス言語

最後、ユビキタス言語ですが、
これはエンジニアとドメインエキスパートの共通言語
のことです。
その業務がどのように動くのか?に注目して作る必要があります。

業界、社内、世界で使われる言葉ではないことに注意してください。
事業部全体や、複数事業で共有したりすると失敗するだろうと書かれています。

共有言語を作るのには時間がかかり、不要に見えるが、 DDDを行う上では必ず共通言語が必要です。

ユビキタス言語を作るヒントは以下の様なものがあるそうです。

  • 用語集(シンプルな定義でまとめたもの)を作る
    • 使えない用語とその理由も書くと尚よし。
  • 用語集がイヤなら、主要な概念のスケッチでもよい。
    • これを叩き台に、新たな用語やフレーズを見つける。
  • 少数メンバーで考えた共通言語を、残りのメンバーにレビューしてもらう。
    • 要望に応じて練り直していく。

共通言語を作るプロセスでドキュメントを作るかもしれませんが、
最もユビキタス言語を表すのは、
チームでの会話コード内のモデル
だそうです。

以上。

8つの事業価値

DDDを行うことによって、どのような事業価値が手に入るか、です。

ここは、私も理解しきれていないので、
師匠の山さんに習って、本に書いてある文章をそのままお伝えします。

  1. 組織として、ドメインに関する有用なモデルを獲得できる。
  2. 事業について、より洗練された正確な定義ができて、さらに深く理解できる。
  3. ドメインエキスパートが、ソフトウェアの設計に貢献できる。
  4. よりよいユーザー体験を提供できる。
  5. モデルとモデルの間に、明確な境界を定められる。
  6. エンタープライズアーキテクチャが、より整理されたものとなる。
  7. アジャイルイテレータブルなモデリングを、継続的に行える。
  8. 戦略的な面でも戦術的な面でも、新しいツールを使える。

次回予告

1章は以上となります。

もう1章、DDDの主要概念を説明した章があり、
その後は実際の設計パターン。デザインパターン、のようなもの、
の紹介となります。

レスポンスがあればまた書こうかな。

Javaでサンプルが書かれてるジャバグラマに優しいDDDの本。