connpass
http://connpass.com/event/3353/
Togetter
http://togetter.com/li/569383
場所は代々木研修室です。
参加者は50人くらいでしょうか。
BPStudyは始めての参加でした。
今回のテーマが増田さんの「ドメイン駆動設計」と和智さんの「組織パターン」の2本立てということで、両方とも非常に興味があったので、ちょうど良い機会ということで参加したのです。
ちょと日が空いてしまいましたが、個人メモを復習用に書き起こしてみる。
■第1部 ドメイン駆動設計入門
発表者: 増田 亨 氏(Twitter:@masuda220)
ドメイン駆動設計入門 from 増田 亨
■1.ソフトウェアの核心「ドメインモデル」
■業務システムの基本構成
・業務システムの場合は、お客さんが使うとこと、他社とのデータ連携などバックがある。
・ドメインモデルを中心に作る、ということは、画面アプリとか連携アプリとかがあり、そのど真ん中に業務のデータとかロジックを集めたドメイン層があって、それを画面から使うことになる。それに拘っていく。
・問題領域に関わるモデルをソフトウェアでまず作る。
■ドメインモデル
・データと業務機能をコードで表現する時に、データと機能を1つのクラスに集約していく。
・データと、それに関連するロジックは一塊にする。さらに、それをビジネス層に集約する。
・データと機能をクラスにまとめる、これに拘る。
・「データ中心アプローチ」と「プロセス思考アプローチ」があるが、DDDでは両方を見ながら固めていけばいい、という発想になる。
・データを考えはじめたら最後までそれやる、とかではなく、「データ」と「機能」を互いに行ったり来たりしながら設計する。
・クラスにカプセル化し、データと機能を結びつける。
・データと機能の関係に注目していくのがDDDの基本中の基本。別れちゃうのはDDD的にアンチパターン。
■関連するデータと機能はクラスにまとめる
(1) 氏名クラス
・氏名オブジェクトがあるとする。そこに「旧姓も知りたい」という要件がある。
・例えば女性が結婚すると苗字が変わるので、苗字はあまりあてにならない。
・そこで、苗字を取得するメソッドとしてoriginalFamilyName()を氏名オブジェクトに持たせる。
・最近は漢字を見ても読み方が良くわからない名前があるので、名前の「カナ」が重要になる。
・その場合は、氏名オブジェクトのキーは「カナ」にし、取得用のnameKana()メソッドを用意する。
(2) 住所クラス
・どの沿線に住んでるかが重要になることがある。そのため沿線を取得するline()メソッドを住所クラスに用意する。
・「駅」じゃなくて「沿線」を気にするドメインにおける設計。
(3) 連絡手段クラス
・曜日や時間によって連絡先を切り替えたいというドメインがあるとする。
・その際は、夜はこの連絡先、土日はこの連絡先、と決め細やかに設定できるようにしたい。
・Firstchoice()メソッドは、曜日とか時間でリターン値が変わってくるメソッド。
(4) 連絡履歴
・連絡履歴というのは仕事上ですごく重要になる。
・例えば連絡を取った直近3人を知るためのメソッドとしてlastThreeContents()を用意したりとか。
このように段々と成長させ、見つけてはクラスとしてプログラムしていくかのがDDDである。
■ドメインモデルをみんなで使う
・業務のデータとロジックはビジネス層に集約させ、それを画面アプリケーションから呼びだす。
・同じドメインモデルを複数のアプリから使って実現していく。
■作る順番
(1) ドメインモデル
・まずドメインモデルを最初に書く。どこの層にも依存させず、独立性の高い形で作る。
(2) データベース
・次にデータベースを作る。モデルからDBを扱えるようORマッピングを行う。
(3) サービス層
・次にサービス層を作る。
・ユーザを登録したいとか、機能要求を実現するための簡単なファサードクラスを用意する。
・各用途ごとに使いやすいようにするサービスクラスを作る。
(4) 機能テスト
・この段階で機能テストする。それより小さいテストはしない。
・ドメインクラスレベルではなく機能レベルでテストを書く。
・ドメイン駆動にはテスト駆動開発は馴染まないと思っている。
・ドメインを探索しているフェーズでは、テストから駆動はありえない。何をテストしていいかわからない。
・それよりも、分析とか思考に力を割いて、落ち着いてからテストを書くようにする。
・ドメイン層のテストには力を入れていない。
・でも機能のテストは自動化に力を入れたい。現状は上手くいってない。
・考え方としては、サービス層まで来たらテストを行う。
(5) アプリケーション
・そのあと、アプリケーションを作る。
・ここではロジックをゴリゴリ書くことは少ない。
---
・ただ、お客さんと話すときはモック画面は早い段階で作るし、デモもする。
・でも、全体の組み立てる順番は(1)~(5)な感じでやっている。
■なぜドメインモデルパターンで作るのか?
・それは、「コード量が減る」から。
・リファクタリングしながら、機能追加しながらドメインモデルに乗せたらコード量が激減した。
・「コード量が減る」というのは、メリットとしては一番大きい気がする。
■コードが減れば
1.テストが減る
2.ドキュメントが減る(もともとあんまり書かないが。。。)
3.バグ調査が楽になる。
4.変更の影響が見通しやすい
ドメインモデルで何が起きているかをトレース出来ていれば原因や場所も特定しやすい。
これらにより、不安感が軽減された。
■ドメインモデルはコードの重複を減らす
・データがあるところで処理すればばいいのに、わざわざgetterメソッドで値を取得してた側で処理するのは「いやな臭い」である。
・集約しましょう。データを持ってるクラスに業務ロジックをまとめる。
・最終的に欲しい値がポンッと返せるクラスにする。
・getterメソッドをみんなが使い始めたら、間違いなくあちこちのクラスに処理が重複している。
■コードが膨張するアンチパターン
(1) トランザクションスクリプト
・「トランザクションスクリプト」とは、機能単位、ボタン単位にスクリプト形式でロジックを書いているようなコードのこと。
・違うボタンがあれば、また同じコードが並んでいる。
・そうなると画面が別でも日付処理が互いに重複したりする。でも日付に対する考え方は統一されているべき。
(2) 使われない共通業務ロジック
・共通業務ロジックって、実はあんまり使われてない。
・ボタン駆動の時に、「共通化したもの使おう」という考えがあんまり沸かない。
・それは、画面単位で分ける設計だと「ここは共通だよね」というコミュニケーションが少なくなるから。
(3) どこでも業務ロジック
・トランザクションスクリプトにさえなってないコード。
・例えばViewやControllerに業務ロジックを書いたりとか。
・例えば「1件もデータが見つからなかった場合はこちらの処理しろ」といのがControllerにあると、それは画面と流れが分離できていない設計である。
(4) SQLに業務ロジックをベタ書き
・SQLのWhere句で演算をしてしまうとか。
・演算がロジックだったばあい、どういう役割分担でやるのかを考える必要がある。
・どれをDDDオブジェクトに振ろう、とかをきちんと設計する。
・SQLに埋め込む情報はDDDオブジェクトから受け取れ、とはしている。でもこれは議論の余地がある。
★ドメインモデル・ビジネス層に業務ロジックを集めましょう!
■ドメインモデルの本当の価値
(1) 業務知識の浸透
・DDDをやると「業務の仕様としてそれはどうなんだ」という議論が増える。そういう活動が多くなる。
・結果として、システムの価値とかの知識がチームに浸透してくる。
・縦割りで機能を割り振るのに比べて、あちこちの機能の連携が理解できるようになる。
・それを2ヶ月くらいやってると、現場の肌感覚とか知恵がチームメンバの中に浸透してくる。
(2) 言語表現を超えた暗黙知が育つ
・業務ロジックはプログラミング言語で表現するが、それを超えた感覚の業務知識が増えてくる。
・例えば、コツとか感どころとか。
・「言葉」としてよりも「感覚」として体に入ってくる。チームの中で暗黙で方向感が出てくる。
(3) あたりがつくようになる。
---
でも、一言でこうなるわけじゃない。DDDを汗かきながらやるのが実態である。
■2.ドメインモデルとオブジェクト思考設計
■個人的な話
・最初はアンチオブジェクト思考だった。
・でもDDDをやる時には、オブジェクト指向のある側面は非常に役に立つ。
・DDD著者のエリック・エヴァンスが、今のメジャーのパラダイスはオブジェクト指向だ。と書いていた。
■部品化アプローチ
(1) 集める
・データとロジックを1つのクラスに集める。マーチン・ファウラーの本にもそう書いてある。
・パッケージの重要性もDDDをやるとすごく意識するようになった。ドメイン層設計のキモかもしれない。
(2) 目的に特化する
・例えばString型には何桁でも入る。
・でもそういう汎用的なものは、プログラム書く際に、結果的に縛りをかける時に不安定になる。
・それならStringではなく「人の名前」というクラスに閉じ込める。
・ガチガチに制約が入ったコードにしておけば、安心して使える。あちこちif文で判定するも必要ない。
・書く行が増えそうだが、実際やってみると、ロジックの散在がなくなってコード量が減ってくる。
・目的に特化するのはとても良いやり方だと実感した。
(3) 業務用語の粒度にあわせた部品
・DDDでいつも粒度の話がでてくるが、考え方は簡単で、「業務用語の粒度」に合わせればいい。
・単語が出てきたら、クラスにする。
・例えば「合計金額」に値と計算ロジックがあれば、クラスにすることで局所化される。
・業務用語を見つけましょう。
■区分と分岐
・ifやswitchでコードを書きまくってると、仕様変更の際にバグの温床になる。
■多態:インタフェース宣言と実装クラス
・実際としてアプリ開発のキモになる。
・業務のロジックを、クラスで分けてしまう。IF文で分けない。これで整理できる範囲はかなり広い。
・この辺をやるとだいぶ楽になった。
■制御構造の再利用
・IoC(制御の反転)
・自分がswitch文で制御をやるんじゃなくて、フレームワークにやらせる。
・フレームワークに制御させることでコードにif文がなくなる。
■補足:パターンについて
・パターンをベタで書くことは最近ほとんど無くなったのが実感。
・昔はGoFのデザインパターンを書いたが、いまはSpringとかでできる。
■3.ドメイン駆動設計のインプット
■最初に手に入れるべき情報とは
・最初に手に入れるべき情報は「ビジネス企画書」である。トップ向けのプレゼン資料とか予算申請資料とか。
・「なぜ予算がとれたのか?」とか、そういうのが重要。
・あとは、「ドメインのガイドブック」も最初に手に入れる。
・手探りじゃお客さんにヒヤリングしてても時間が足りない。
・3種類の本を読む。
①簡単な本
②分厚い本
③薄い英語本
・③は、クラス名とか見つけやすい。巻末のインデックスからクラス名を探す。
・あちこちからリファレンスされている用語をクラス名にする。
・クラス名で悩むくらいなら、薄い英語の本を買いましょう。
■いつも気にすべき情報
・気にすべきことは「言葉」。
・ちょっとした会話でも気にしないとDDDではダメである。
・お客さんとの会話で、モデルの中の言葉で説明できるのかを気にする。
■データと機能
・重要なのは「データ」と「機能」のハイブリッドなアプローチ。
・常に、「データ」と関連する「機能」を対にする。それが一番の重要ポイント。
■ドメイン駆動設計の基本スタイル
・プロセス大事。繰り返さないとリズムが出てこないので、リズムを意識する。
・目的に特化したほうが楽になる。
・一発で良い設計なんてできないので、リファクタリングしながら育てていく。
第2部 『組織パターン』の読み方
発表者:和智右桂氏(Twitter:@digitalsoul0124)
![]() | 組織パターン (Object Oriented SELECTION) (2013/08/06) James O. Coplien、Neil B.Harrison 他 商品詳細を見る |
講演スライドは公開されていないようで、無念。。。
ということで手元のメモを起こしてみる。
■組織パターン
・組織パターンには何が書かれているのか、と言われると結構難しい。でも敢えて言えば「パターン集」ではない。
・ノウハウをすべて吸収して読もうとすると、パターン数が多くて迷子になる。
・パターン1個1個に価値はあるが、読むときはふわっと全体を掴むようにしたほうが取っ掛かりが良い。
・巨大ウォーターフォールや精鋭アジャイルといった、どちらの極にも振らないもう1つの答えが組織パターン。
・成長するチームがソフトウェアを育てる。これが組織パターンの原風景。
■パターンとは
・アジャイル手法はパッケージにされる。例えば「XP」とか「Scrum」とか。これとこれをやりなさい、とか。
・James O. Coplienはそういう方法はとらない。この本を手に組織改革をしないでくれ、と書いている。
■パターンの定義
・ソフトウェア開発で有名なのはデザインパターン。
・オブジェクト指向で設計する時によく出てくる問題の対処方法をパターンにした。
・パターンは繰り返し現れる。
・あるコンテキストにおける問題を解決する。
・ある問題を解決すれば別の問題がまた生まれる。その問題を解決するためのパターンが続く。
・これが組織の成長のプロセスと重なっている。パターンの繋がりがパターン言語である。
・書籍には100個くらいのパターンがあり、繋がりでまとめられてる。
・このパターンを解決すると、次にはこのパターンに続くことが多いよね、とか。
・プロセスに従っているから大丈夫だよね、という思考停止が一番問題。
■4つのパターン言語
・プロジェクトマネジメント
・組織の漸進的成長
・組織のスタイル
・人とコード
■プロジェクトマネジメント
目立つところを取り出すと
・スケジュールの細分化
・継続的なデリバリー
・バックログ
こういうのがプロジェクトマネジメントのパターン言語では目に引く。
スクラムの源泉。いわゆるアジャイル系。
■組織の漸進的成長
(1) 小さい組織を徐々に大きく
・そうするにはどうすればいいか?
・人を段階的に増やしましょう。
(2) 多様性が重要
・優秀な人が集まったグループって、ワークショップの結果にブレークスルーがあまりない。
・チームに同じ属性の人が集まると、突き抜けない。
・それよりも、最初はバラバラだと思ったチームの方が突き抜けることが多い。
・多様性に富んだチームが結果を出す。男と女とか、国籍の違いとか、会社の違いとか。
・多様性はJames O. Coplienの主張にある源泉。
(3) トラックナンバーを少なく
・「トラックナンバー」とは、プロジェクトのメンバーの内、トラックに轢かれるとプロジェクトが継続困難になる人数のこと。
・トラックナンバーをなるべく少なくしましょう。
■組織のスタイル
(1) 分割統治
大きいものは分けましょう。
(2) コンウェイの法則
・ソフトの構造は組織の構造に似せなければいけない。これが分けるコツ。
(3) 生産者を中心に
・コードを書く人に情報が流れるようにしましょう。
・指揮官が中心にいるようではダメ。価値が生み出す人に情報が流れるようにする。
■人とコード
・アーキテクチャ重要
・情報共有重要
・インタフェース重要(実装は意識しなくてよいように)
■作業が内側に流れる(4.1.18節)
・開発者が真ん中にいて、開発者がPMとか顧客と直接会話しましょう。
・ステークホルダーと開発者の間には防火壁を入れましょう。
■コンウェイの法則(5.1.7節)
・和智さんが大好きな法則。
・オフショア開発とかは当てはまるのでは。
■現場に根ざしたノウハウ
(1) 細かいリスケをしない
(2) 暗黙的な要件
・細かい要件はあとから出てくる。暗黙的な要件があることを見込みましょう。
(3) 常に誰かが進捗させる
・何か問題がおきても、スケジュールに沿って進める人を残しましょう。全員で問題に当たるな。
■まとめ
・全体感を捉えつつ、個別の話を読むのが面白いのでは。
・組織パターンで一番重要なのは、「道はひとつではない」ということ。
・すごく美しい世界が展開されているわけではない。
・自分の組織を批判する道具としては使わないでほしい。
・書籍に改善できるヒントがあれば、是非改善していってほしい。
★感想:
第1部のドメイン駆動設計ですが、増田さんの講演は今回で3回目くらいです。
そういう意味では、いつもと違う切り口で話してくださって、重複も少なく良かったです。
1時間じゃ足りずに4章の実装の話がほぼ駆け足になったので、1時間半くらいあっても良かったのかも。
大変参考になりました。ちょうどDDDの読書会にも参加中のことだし。
![]() | エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践) (2011/04/09) エリック・エヴァンス 商品詳細を見る |
第2部の「組織パターン」ですが、これは元々興味があった本なんですよね。
ちなみに講演者の和智さんは↑のDDD本の訳者でもあります。
んで図書館には予約を入れていたんですが、この日の講演には間に合わず。
その後、無事借りられました。(まだ読んでいませんが)
こーゆう分厚い本は漠然と読むよりは、ポイントを理解したうえで読むのが大事だと思っています。
なのでこの日の講演でその辺が聞けてよかったです。
講演者様、スタッフ様、皆様ありがとうございました。
- 関連記事
-
- 豆ナイト Presents 「DAD はアジャイル開発の決定打となるのか?」に参加しました
- 「BPStudy#73」に参加しました。
- SQLアンチパターン読書会 「ラウンディングエラー」 に参加しました