読者です 読者をやめる 読者になる 読者になる

There's an echo in my head

日々のメモ。

java-ja.dddに行ってきた

java-ja development architecture

グリーさんで開かれたjava-ja.dddに行ってきた。

JavaAndroidアプリを作るときにちょっと触った程度しか経験がないし、エンタープライズな開発も経験がないけど面白かった。ドメイン駆動設計の本はほとんど読まずに積読になっているので今度読もう。

各種まとめはyamashiroさんのgistから。

増田さんの名前探しと小さく作る話はとても面白かった。ドメインの登場人物をすべてオブジェクトに落としこむことでNULLを出さない、などなど。小さく小さく作ることで部分部分での処理を明確化するというのは、難しいけどやってみたいなぁ。

t-wadaさんのLTもActiveRecordに関する話で面白かったけど、資料が無いorz t-wadaさんとjoker1007さんのやりとりもまた面白いのでまた読み返す。

以下、当日のメモ。

業務知識を反映して開発する→柔軟に変化する

ビジネス的な制約は見やすくする
xがy%を超えてたらzを通さない → この制約を表すクラスとして表現する

* ifだと埋もれる
* やり過ぎるとクラスが増えすぎる(EnterprizeFizzBuzz)

ドメインエキスパートと話をする→整理する→モデルに落としこんでみる→書いてみる→モデルを修正する→繰り返す
モデル:オブジェクト(DBだけだとちょっと足りない)
ドメインエキスパート: ロジック、データ構造を知ってる人

---

名前探しの旅

名前大事
名前の違和感→リファクタリング

業務の言葉とソフトウェア開発の言葉は違う
業務の言葉をオブジェクトで書く
(これが受け入れられなければ、DDD側でなくソフトウェアでの開発に専念したほうがその人のため)

ドメインエキスパート、このひとだけに聞けば大丈夫って人はいない。
鵜呑みにしていいもんでもない。彼らが答えを知っているとは限らない。

名前は英語

トランザクションスクリプトは流れだけを書く
さわるのはイベント、記録、通知ぐらい
あとは移譲する

ソフトウェア的な視点だけから重複の削減はしてはいけない
業務が別として認識している→ソフトウェア上も別で実装する
たとえ一つのモジュールにまとめられたとしても、変更がかかる可能性が高い
コードの重複を削減する際は、ビジネス的背景も重複してるか考える

* 良い名前
* 小さく作る
* ばらばらにする

良い名前の見つけ方:

* 語彙を増やす(読む、調べる、聞く、尋ねる)
* 正しく使う
* 類似のパッケージのカタログ等
    * 類似の英語サービスのヘルプ(流通→Amazon、とか)

* 話す→関心度→仕様変更の可能性

★小さく作る:

クラス50行以内、メソッド3-10行以内
分割できないか、クラスに切り出せるんじゃないか。

小さく切り出すことで単体テストが要らなくなってくる
(結合テストは大事)

★ドメイン内ではオブジェクト・メソッドを専用化する。汎用化されてたものをドメインの言葉で専用化する。
ドメイン内で作ったものがほかのドメインに再利用できるとは考えない
date.add_date(-1) -> date.previous_date -> date.final_alert_date

★ifを減らす
enum
strategy/state
missing object
hash

ドメインの中でnullが飛び交うことはない

★forを使わない
ファーストクラスコレクション、コレクション操作を専門的に扱うクラスを用意する

Deque(デック)

★setterを使わない
完全コンストラクタ、生成時に必要な値を全てセット

★getterを使わない
ドメイン内での話、フレームワークは別。
ロジックをオブジェクトの中に隠蔽して処理の結果を受け取るようにする

★構造の変更に備える

* 安易に継承しない、似たものでも同じデータを持つとは限らない
* ドメインのオブジェクトは深い名前空間で持たない。フラットに、ばらばらにしておく。
* publicは避ける

@joker1007<http://twitter.com/joker1007/status/315083832439214080>
ドメインオブジェクトの中でimport文が増える、つまり色んなクラスが必要になるってのは、余計な事をやり過ぎのサインかもしれない。

ドメイン間をまたいで例外が投げられることはない
たとえばファイルのパースができなくて例外が投げられることはあるけど、それはその処理を行うオブジェクトのなかで完結すべき。

-- 

t_wada

ActiveRecordパターン、ドメインモデル貧血症(Getter/Setterのみで振る舞いがない)
→モデルがコントローラに密結合する

これが許される場面:

* 管理画面など画面とレコードが1体1対応する
* プロトタイプ開発など技術的負債に自覚的

ソフトウェアの複雑性は結局変わらないから複雑性の置き場所を考える

モデルは意図ややり取りのI/Fを提供するもの、
クエリを投げるためのI/Fじゃない

ドメインモデルがActiveRecordを持つようにする
コントローラとの間に層を持つ、疎結合にしてデータ層(物理層)の変更に対してドメイン層(論理層)に柔軟性をもたせる

Railsの場合、論理層のバリデーションはActiveModel::Validationsで行う
(ActiveRecord側のバリデーションはあくまでもDBに保存する値のチェック)

あと当日のツイートもメモ。

ブルーオーシャンとかスタートアップでもドメインってものがあるのかどうかという質問があって感じたこと。「ドメイン=世界観」だと考えると、まだこの世に存在しない・稼働していないものであっても、なにかしらの構造や振る舞いがあるのならそれこそがドメインになるのだと思う。エンタープライズのほうが複雑な構造を持つものを扱いやすいってだけで、BtoCやスタートアップにもドメインはある。

増田さんの発表のなかで、文字列をIntとしてパースしようとしたとかそういうレベルでの例外は発生するけど、ドメインのなか(上位のレイヤー間)で例外があがることはありえないという話に「なるほどなぁ」と思った。例えばある欄が未記入のフォームを扱うオブジェクトがあるとしたら、それは「未記入という例外を投げる」のではなく「未記入という状態を持つオブジェクトという前提でやりとりをする」というような話、だった気がする。

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。