「ドメイン駆動設計のためのオブジェクト指向プログラミングハンズオン」第2回でユーザー定義型を自分で作ってみた

ちょうど弊社内の同僚と輪読会をしていた書籍の著者であるところの増田さんがやるハンズオンがあると聞いて行ってきた。

第一回はこちら。動画で見てもなかなかおもしろかった。

youtu.be

アソビューについて

www.asoview.com の運営会社。

椅子がキャンプ用のやつで、会社特有感出てて面白い。

テーマは「型」

型とは、オブジェクトにおいて有効な値および演算を定義するもの = ストラウストラップ先生の受け売り。

ユーザー定義型を作って、モデルと実装を一致させるハンズオン

前説自体は、よくあるオブジェクト指向の概念の説明。 コードの臭いとか、リファクタリングの話とか。

ネタは「購入の平均単価」。 f:id:blackawa:20171018202021j:plain

このビューを表現するユーザー定義型を実装しよう。 以下は、やりながら感じたことの箇条書き。

自分がどんなロジックで生成されるかは、誰が知るべき?

売上高 / 購入量 

で導出される「平均単価」のインスタンス生成方法は、誰が知るべき? コンストラクタの引数か?

だとすると、

売上高.割る(購入量);

するための divide メソッドの中身は、ただのインスタンス生成になってしまう...。 その場では、「割り算処理とはAveragePriceを返すことである」と表現できるかなと思って、それで終わりにした。

とはいえ計算には基本データ型が必要になる

Price + Price

とは書けないので足し算を実装する必要があるが、そのためにはせっかくユーザー定義型を作ったのに基本データ型に変換する必要が出てきてしまう。 それではせっかくラップした基本データ型が外部に露出してしまって、隠蔽した意味がなくなってしまう。 結局内部のデータ型が変更されたら変更が広がってしまう...。

結局この疑問はハンズオン中に解消できなくて、最後に増田さんに質問しに行った。 そしたら

  • 「自分と同じクラスのインスタンスを引数に取るなら、引数インスタンスのprivateなプロパティにアクセスできるから、その性質を利用して計算する」
  • 「あるオブジェクトをIntegerやLongに直す関数は、Javaのお作法といえるくらい一般的な手法だから、そういうメソッドを生やしてしまう」

とのことだった。1つめの、同じクラス内でならprivateプロパティにアクセスできる、というのは今まで知らなかった! privateという言葉の直感には反する挙動だけど、基本データ型を露出しないというルールを実現するには筋の良い手段だと思った。

同じ机の人が全員違うドメインロジックを想像する、という事実自体が大事

クラス数が3個の人もいれば15個の人もいる。 しかもそれらは比較的小さなクラス。

すると、それぞれのメンバーがどれくらい違うドメインモデルを想像しているのかが明確になった。 増田さんいわく、それらはどれが正解ってわけではなくて、理解が異なっていることが分かることが大事だという。

たしかに、実プロジェクトでこれくらい小さなクラスとパッケージの集合を作れたら、仕様の認識合わせがすごく楽そうだ。

懇親会

懇親会にもお邪魔して、アソビューの社員の方に話を伺えた。 Java(SpringBoot)で増田さん流のDDDを実現しようとしている会社として、どんなことをしているのか気になったので質問してきた。

アソビューは最初からJavaだったのか?どのタイミングで事業の開発スピードとDDDを両立したのか?

最初からJavaだったけど、お金になるとわかった時点でDDD化を検討しはじめて、今粛々と書き直しているところ。 いうても巨大なシステムなので、まだまだ道半ばではあるが、すでにDDD化されたサブシステムの変更コストが軽くなっているのは実感している。

フロントとバックで共通のドメインが出てくるんじゃないかと思うが、共通モジュール化する?

個人ユーザー向けシステムと出展企業向けシステムで同じ言葉を使うとしても、実態は異なるドメインなので、ドメインは共通化させないで始めると思う。 もし、「これだけは確実に同じドメインでしょ」というようなものが出てきたら、その時に初めて共通化を検討する。