×
  • Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
 

実践的な設計って、なんだろう?

on

  • 386 views

Devlove 名古屋 2014-5-18 DDD, Object Oriented Design, ドメイン駆動設計 オブジェクト指向設計

Devlove 名古屋 2014-5-18 DDD, Object Oriented Design, ドメイン駆動設計 オブジェクト指向設計

Statistics

Views

Total Views
386
Views on SlideShare
383
Embed Views
3

Actions

Likes
3
Downloads
3
Comments
2

2 Embeds 3

https://twitter.com 2
https://www.chatwork.com 1

Accessibility

Categories

Upload Details

Uploaded via SlideShare as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

12 of 2 previous next

Post Comment
Edit your comment

    実践的な設計って、なんだろう? 実践的な設計って、なんだろう? Presentation Transcript

    • 実践的な設計って なんだろう? ギルドワークス株式会社 増田 亨 DevLove Nagoya 2014/5/19
    • Agile is dead. TDD is dead. Long live the DDD.
    • 正しいものを正しくつくる!!
    • プロセスやツールよりも 正しいものを正しくつくる!!
    • たいせつなのは設計なんですよ プロセスやツールよりも 正しいものを正しくつくる!!
    • たいせつなのは設計なんですよ 設計 プロセスやツールよりも 正しいものを正しくつくる!!
    • 設計ってなんだろう?
    • コードを整理整頓する工夫 設計ってなんだろう?
    • なんのために?
    • なんのために? 変更コストを下げたい
    • 設計とは 変更コストを下げるために コードを整理整頓する 実践的な工夫
    • 「実践的」ってなんだろう?
    • 「実践的」ってなんだろう? 全体 部分
    • 「実践的」ってなんだろう? 全体 部分 長期 短期
    • 「実践的」ってなんだろう? 全体 部分 広さ 深さ 長期 短期
    • 「実践的」ってなんだろう? 全体 部分 論理 感覚 広さ 深さ 長期 短期
    • 「実践的」ってなんだろう? 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期
    • 「実践的」ってなんだろう? 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期 行ったり来たり動きながらバランスを取る
    • 実践的な設計 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期 左右のバランスを取りながら 変更コストを下げる工夫を続ける
    • 具体的にどうやるの?
    • 具体的にどうやるの? 変更コストの原因を知る
    • 変更コストの最大の敵
    • 変更コストの最大の敵 重複したコード
    • 変更コストの最大の敵 重複したコード あちこち調べ
    • 変更コストの最大の敵 重複したコード あちこち調べ あちこち直し
    • 変更コストの最大の敵 重複したコード あちこち調べ あちこち直し 思わぬ副作用と格闘する
    • 重複したコードのいやな臭い
    • 重複したコードのいやな臭い 長いメソッド
    • 重複したコードのいやな臭い 長いメソッド 大きなクラス
    • 重複したコードのいやな臭い 長いメソッド 大きなクラス たくさんの引数
    • 重複したコードのいやな臭い 長いメソッド 大きなクラス たくさんの引数 同じコードがあちこちに 書かれている臭いがする
    • マスダ流 重複の臭い判定基準
    • マスダ流 重複の臭い判定基準 クラス 50行 メソッド 3行 引数 0
    • マスダ流 重複の臭い判定基準 クラス 50行 メソッド 3行 引数 0 これを超えたら警戒警報
    • マスダ流 重複の臭い判定基準 クラス 50行 100行 メソッド 3行 5行 引数 0 1
    • マスダ流 重複の臭い判定基準 クラス 50行 100行 メソッド 3行 5行 引数 0 1 これを超えたら 一息いれて設計やり直し
    • コード整理の基本パターン
    • コード整理の基本パターン Value Object
    • コード整理の基本パターン Value Object 振る舞いを持った区分
    • コード整理の基本パターン Value Object 振る舞いを持った区分 ファーストクラスコレクション
    • Value Object パターン
    • Value Object パターン privateなデータ + public な振る舞い
    • Value Object パターン privateなデータ + public な振る舞い 不変(immutable)
    • Value Object パターン privateなデータ + public な振る舞い 不変(immutable) 例:String型
    • Value Object パターン privateなデータ + public な振る舞い 不変(immutable) private final char value[]; private final int count; String substring() { … } String trim() { … } int length() { … } boolean startsWith { … } 例:String型
    • Value Object パターン getValue()しない
    • Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる
    • Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる だから
    • Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる だから データのある場所に ロジックを寄せる
    • Value Object パターン setValue()しない
    • Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる
    • Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる だから
    • Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる だから 不変オブジェクトにする
    • 業務アプリの Value Object
    • 業務アプリの Value Object String StringBuilder List<String>
    • 業務アプリの Value Object String StringBuilder List<String>+業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Calendar Date/Long 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 起算日(InitialDate) 期限(DueDate) 有効期間(ValidTerm) 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
    • 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 起算日(InitialDate) 期限(DueDate) 有効期間(ValidTerm) 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
    • 振る舞いを持った区分
    • 振る舞いを持った区分 enum MemberType { normal, silver, gold }
    • 振る舞いを持った区分 MemberType type = gold; gold.chargeRate() gold.description() gold.isLimitOver()
    • 振る舞いを持った区分 区分定数に 業務の知識を持たせる MemberType type = gold; gold.chargeRate() gold.description() gold.isLimitOver()
    • 振る舞いを持った区分 CodeIQ で出題中 (6月2日まで) 「顧客区分」を列挙型で宣言し、 「顧客区分」ごとに異なる振る舞い を持たせてみましょう。
    • ファーストクラスコレクション
    • ファーストクラスコレクション privateなコレククション + public な振る舞い private final char value[]; private final int count; String substring() { … } String trim() { … } int length() { … } boolean startsWith { … } 例:String型
    • ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する
    • ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから
    • ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから コレクションを持つクラスに ループ処理を閉じ込めて
    • ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから コレクションを持つクラスに ループ処理を閉じ込めて 一元管理する
    • ファーストクラスコレクション
    • ファーストクラスコレクション 顧客一覧 (Customers)
    • ファーストクラスコレクション 顧客一覧 注文明細 (Customers) (OrderLines)
    • ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 (Customers) (OrderLines) (UsageHistory)
    • ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト (Customers) (OrderLines) (UsageHistory) (ToDoList)
    • ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト 未読一覧 (Customers) (OrderLines) (UsageHistory) (ToDoList) (UnReads)
    • ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト 未読一覧 選択候補 (Customers) (OrderLines) (UsageHistory) (ToDoList) (UnReads) (Candidates)
    • コードの整理 アンチパターン
    • コードの整理 アンチパターン Smart UI
    • コードの整理 アンチパターン Smart UI トランザクションスクリプト
    • コードの整理 アンチパターン Smart UI トランザクションスクリプト Active Record
    • コードの整理 アンチパターン Smart UI トランザクションスクリプト Active Record 必ずコードが重複する
    • コードの整理 アンチパターン 画面仕様書
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書 機能単位で開発
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書 機能単位で開発 トランザクション スクリプト
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 トランザクション スクリプト
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル 定義書 トランザクション スクリプト
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複 テーブルに関連 づかないコードの 氾濫と重複 機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
    • コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複 テーブルに関連 づかないコードの 氾濫と重複 機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
    • コードの整理 グッドパターン
    • コードの整理 グッドパターン 三層+ドメインモデル
    • コードの整理 グッドパターン プレゼンテーション層 ビュー 画面コントローラ 三層+ドメインモデル ドメインモデル
    • コードの整理 グッドパターン プレゼンテーション層 ビュー 画面コントローラ 三層+ドメインモデル ドメインモデル 業務ロジック
    • コードの整理 グッドパターン ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層+ドメインモデル 業務ロジック ドメインモデル プレゼンテーション層 ビュー 画面コントローラ
    • コードの整理 グッドパターン 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ
    • コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル 業務ロジック 業務ロジック ドメインモデル ビジネスロジック層 (サービス層) アプリケーション コントローラ プレゼンテーション層 ビュー 画面コントローラ
    • コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ
    • コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層に散らばりがちな 業務ロジックの断片を ここに集めて一元化する
    • ドメインモデルの設計のコツ
    • ドメインモデルの設計のコツ 画面単位に設計しない
    • ドメインモデルの設計のコツ 画面単位に設計しない 機能単位に設計しない
    • ドメインモデルの設計のコツ 画面単位で設計しない 機能単位に設計しない テーブル単位に設計しない
    • じゃあどうすればよい?
    • じゃあどうすればよい? 業務の関心事を表現できるように クラスを考える
    • 業務の関心事(業務知識)
    • 業務の関心事(業務知識) 1. ポイントカード口座会員 2. 購入金額に応じてポイントを提供 3. 本人確認をすることがある 4. 精算後のポイント加算はできない 5. ポイントの有効期限は2年 6. ポイントは換金しない 7. 返品・交換により累計ポイントが マイナスになる場合は現金で精算
    • ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する
    • ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する 画面/機能/テーブル単位のコード整理とは 異なる切り口のクラス設計
    • なぜドメインモデルなの?
    • なぜドメインモデルなの? コードが重複しない
    • なぜドメインモデルなの? コードが重複しない 変更が簡単
    • なぜコードが重複しないか?
    • なぜコードが重複しないか? 関心事単位の整理だから
    • なぜコードが重複しないか? 関心事単位の整理だから 画面/機能/テーブル単位の コード整理は重複する
    • なぜ変更が簡単か?
    • なぜ変更が簡単か? 仕様変更は業務から発生する
    • なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる
    • なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている
    • なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている 影響範囲がわかりやすい
    • なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている 影響範囲がわかりやすい 変更の対象箇所以外でわけの わからない副作用がおきない
    • ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する 画面/機能/テーブル単位のコード整理とは 異なる切り口のクラス設計
    • コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層に散らばりがちな 業務ロジックの断片を ここに集めて一元化する
    • たいせつなのは設計なんですよ 設計 プロセスやツールよりも 正しいものを正しくつくる!!
    • 設計とは 変更コストを下げるために コードを整理整頓する 実践的な工夫