Anzeige

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

ソフトウェアシステムの設計・構築 um システム設計
17. May 2014
Anzeige

Más contenido relacionado

Presentaciones para ti(20)

Anzeige

Similar a 実践的な設計って、なんだろう?(20)

Más de 増田 亨(20)

Anzeige

Último(20)

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

  1. 実践的な設計って なんだろう? ギルドワークス株式会社 増田 亨 DevLove Nagoya 2014/5/19
  2. Agile is dead. TDD is dead. Long live the DDD.
  3. 正しいものを正しくつくる!!
  4. プロセスやツールよりも 正しいものを正しくつくる!!
  5. たいせつなのは設計なんですよ プロセスやツールよりも 正しいものを正しくつくる!!
  6. たいせつなのは設計なんですよ 設計 プロセスやツールよりも 正しいものを正しくつくる!!
  7. 設計ってなんだろう?
  8. コードを整理整頓する工夫 設計ってなんだろう?
  9. なんのために?
  10. なんのために? 変更コストを下げたい
  11. 設計とは 変更コストを下げるために コードを整理整頓する 実践的な工夫
  12. 「実践的」ってなんだろう?
  13. 「実践的」ってなんだろう? 全体 部分
  14. 「実践的」ってなんだろう? 全体 部分 長期 短期
  15. 「実践的」ってなんだろう? 全体 部分 広さ 深さ 長期 短期
  16. 「実践的」ってなんだろう? 全体 部分 論理 感覚 広さ 深さ 長期 短期
  17. 「実践的」ってなんだろう? 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期
  18. 「実践的」ってなんだろう? 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期 行ったり来たり動きながらバランスを取る
  19. 実践的な設計 全体 部分 論理 感覚 理想 現実 広さ 深さ 長期 短期 左右のバランスを取りながら 変更コストを下げる工夫を続ける
  20. 具体的にどうやるの?
  21. 具体的にどうやるの? 変更コストの原因を知る
  22. 変更コストの最大の敵
  23. 変更コストの最大の敵 重複したコード
  24. 変更コストの最大の敵 重複したコード あちこち調べ
  25. 変更コストの最大の敵 重複したコード あちこち調べ あちこち直し
  26. 変更コストの最大の敵 重複したコード あちこち調べ あちこち直し 思わぬ副作用と格闘する
  27. 重複したコードのいやな臭い
  28. 重複したコードのいやな臭い 長いメソッド
  29. 重複したコードのいやな臭い 長いメソッド 大きなクラス
  30. 重複したコードのいやな臭い 長いメソッド 大きなクラス たくさんの引数
  31. 重複したコードのいやな臭い 長いメソッド 大きなクラス たくさんの引数 同じコードがあちこちに 書かれている臭いがする
  32. マスダ流 重複の臭い判定基準
  33. マスダ流 重複の臭い判定基準 クラス 50行 メソッド 3行 引数 0
  34. マスダ流 重複の臭い判定基準 クラス 50行 メソッド 3行 引数 0 これを超えたら警戒警報
  35. マスダ流 重複の臭い判定基準 クラス 50行 100行 メソッド 3行 5行 引数 0 1
  36. マスダ流 重複の臭い判定基準 クラス 50行 100行 メソッド 3行 5行 引数 0 1 これを超えたら 一息いれて設計やり直し
  37. コード整理の基本パターン
  38. コード整理の基本パターン Value Object
  39. コード整理の基本パターン Value Object 振る舞いを持った区分
  40. コード整理の基本パターン Value Object 振る舞いを持った区分 ファーストクラスコレクション
  41. Value Object パターン
  42. Value Object パターン privateなデータ + public な振る舞い
  43. Value Object パターン privateなデータ + public な振る舞い 不変(immutable)
  44. Value Object パターン privateなデータ + public な振る舞い 不変(immutable) 例:String型
  45. Value Object パターン privateなデータ + public な振る舞い 不変(immutable) private final char value[]; private final int count; String substring() { … } String trim() { … } int length() { … } boolean startsWith { … } 例:String型
  46. Value Object パターン getValue()しない
  47. Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる
  48. Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる だから
  49. Value Object パターン データをget()して 加工/計算/判断すると、 ロジックが散らばる だから データのある場所に ロジックを寄せる
  50. Value Object パターン setValue()しない
  51. Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる
  52. Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる だから
  53. Value Object パターン データを 加工/計算/判断して set()すると 状態管理のコードが散らばる だから 不変オブジェクトにする
  54. 業務アプリの Value Object
  55. 業務アプリの Value Object String StringBuilder List<String>
  56. 業務アプリの Value Object String StringBuilder List<String>+業務ロジック
  57. 業務アプリの Value Object String StringBuilder List<String> 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック
  58. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック
  59. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
  60. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
  61. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Calendar Date/Long 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック
  62. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
  63. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 起算日(InitialDate) 期限(DueDate) 有効期間(ValidTerm) 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
  64. 業務アプリの Value Object String StringBuilder List<String> BigDecimal Integer Caleldar Date/Long 起算日(InitialDate) 期限(DueDate) 有効期間(ValidTerm) 金額(Money) 数量(Quantity) 単位(Unit) 商品名称(ProductName) 備考(Remarks) 摘要(Abstract) +業務ロジック +業務ロジック +業務ロジック
  65. 振る舞いを持った区分
  66. 振る舞いを持った区分 enum MemberType { normal, silver, gold }
  67. 振る舞いを持った区分 MemberType type = gold; gold.chargeRate() gold.description() gold.isLimitOver()
  68. 振る舞いを持った区分 区分定数に 業務の知識を持たせる MemberType type = gold; gold.chargeRate() gold.description() gold.isLimitOver()
  69. 振る舞いを持った区分 CodeIQ で出題中 (6月2日まで) 「顧客区分」を列挙型で宣言し、 「顧客区分」ごとに異なる振る舞い を持たせてみましょう。
  70. ファーストクラスコレクション
  71. ファーストクラスコレクション privateなコレククション + public な振る舞い private final char value[]; private final int count; String substring() { … } String trim() { … } int length() { … } boolean startsWith { … } 例:String型
  72. ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する
  73. ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから
  74. ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから コレクションを持つクラスに ループ処理を閉じ込めて
  75. ファーストクラスコレクション コレクションをget()して 操作すると あちこちに同じコードが登場する だから コレクションを持つクラスに ループ処理を閉じ込めて 一元管理する
  76. ファーストクラスコレクション
  77. ファーストクラスコレクション 顧客一覧 (Customers)
  78. ファーストクラスコレクション 顧客一覧 注文明細 (Customers) (OrderLines)
  79. ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 (Customers) (OrderLines) (UsageHistory)
  80. ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト (Customers) (OrderLines) (UsageHistory) (ToDoList)
  81. ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト 未読一覧 (Customers) (OrderLines) (UsageHistory) (ToDoList) (UnReads)
  82. ファーストクラスコレクション 顧客一覧 注文明細 利用履歴 To-do リスト 未読一覧 選択候補 (Customers) (OrderLines) (UsageHistory) (ToDoList) (UnReads) (Candidates)
  83. コードの整理 アンチパターン
  84. コードの整理 アンチパターン Smart UI
  85. コードの整理 アンチパターン Smart UI トランザクションスクリプト
  86. コードの整理 アンチパターン Smart UI トランザクションスクリプト Active Record
  87. コードの整理 アンチパターン Smart UI トランザクションスクリプト Active Record 必ずコードが重複する
  88. コードの整理 アンチパターン 画面仕様書
  89. コードの整理 アンチパターン 画面仕様書 画面単位で開発
  90. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム
  91. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複
  92. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書
  93. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書 機能単位で開発
  94. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能仕様書 機能単位で開発 トランザクション スクリプト
  95. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 トランザクション スクリプト
  96. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル 定義書 トランザクション スクリプト
  97. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト
  98. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
  99. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複 テーブルに関連 づかないコードの 氾濫と重複 機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
  100. コードの整理 アンチパターン 画面仕様書 画面単位で開発 Smart UI プログラム 画面Aと画面Bで コード重複 機能Aと機能Bで コード重複 テーブルに関連 づかないコードの 氾濫と重複 機能仕様書 機能単位で開発 テーブル単位で開発 テーブル 定義書 トランザクション スクリプト Active Record
  101. コードの整理 グッドパターン
  102. コードの整理 グッドパターン 三層+ドメインモデル
  103. コードの整理 グッドパターン プレゼンテーション層 ビュー 画面コントローラ 三層+ドメインモデル ドメインモデル
  104. コードの整理 グッドパターン プレゼンテーション層 ビュー 画面コントローラ 三層+ドメインモデル ドメインモデル 業務ロジック
  105. コードの整理 グッドパターン ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層+ドメインモデル 業務ロジック ドメインモデル プレゼンテーション層 ビュー 画面コントローラ
  106. コードの整理 グッドパターン 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ
  107. コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル 業務ロジック 業務ロジック ドメインモデル ビジネスロジック層 (サービス層) アプリケーション コントローラ プレゼンテーション層 ビュー 画面コントローラ
  108. コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ
  109. コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層に散らばりがちな 業務ロジックの断片を ここに集めて一元化する
  110. ドメインモデルの設計のコツ
  111. ドメインモデルの設計のコツ 画面単位に設計しない
  112. ドメインモデルの設計のコツ 画面単位に設計しない 機能単位に設計しない
  113. ドメインモデルの設計のコツ 画面単位で設計しない 機能単位に設計しない テーブル単位に設計しない
  114. じゃあどうすればよい?
  115. じゃあどうすればよい? 業務の関心事を表現できるように クラスを考える
  116. 業務の関心事(業務知識)
  117. 業務の関心事(業務知識) 1. ポイントカード口座会員 2. 購入金額に応じてポイントを提供 3. 本人確認をすることがある 4. 精算後のポイント加算はできない 5. ポイントの有効期限は2年 6. ポイントは換金しない 7. 返品・交換により累計ポイントが マイナスになる場合は現金で精算
  118. ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する
  119. ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する 画面/機能/テーブル単位のコード整理とは 異なる切り口のクラス設計
  120. なぜドメインモデルなの?
  121. なぜドメインモデルなの? コードが重複しない
  122. なぜドメインモデルなの? コードが重複しない 変更が簡単
  123. なぜコードが重複しないか?
  124. なぜコードが重複しないか? 関心事単位の整理だから
  125. なぜコードが重複しないか? 関心事単位の整理だから 画面/機能/テーブル単位の コード整理は重複する
  126. なぜ変更が簡単か?
  127. なぜ変更が簡単か? 仕様変更は業務から発生する
  128. なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる
  129. なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている
  130. なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている 影響範囲がわかりやすい
  131. なぜ変更が簡単か? 仕様変更は業務から発生する 業務の関心事単位のクラスなら 変更箇所を1対1で特定できる 業務の関心事の依存関係が クラスの依存関係になっている 影響範囲がわかりやすい 変更の対象箇所以外でわけの わからない副作用がおきない
  132. ドメインモデル(関心事の模型) 会員 (entity) ポイント口座 (account) 購入 (event) 返品・交換 (event) 有効期限 (policy) 購買履歴 (status) 換金率 (policy) 残高 (status) 本人確認情報 (description) 加算する 参照する 画面/機能/テーブル単位のコード整理とは 異なる切り口のクラス設計
  133. コードの整理 グッドパターン データアクセス層 データアクセス オブジェクト 三層+ドメインモデル ドメインモデル 業務ロジック 業務ロジック 業務ロジック プレゼンテーション層 ビュー 画面コントローラ ビジネスロジック層 (サービス層) アプリケーション コントローラ 三層に散らばりがちな 業務ロジックの断片を ここに集めて一元化する
  134. たいせつなのは設計なんですよ 設計 プロセスやツールよりも 正しいものを正しくつくる!!
  135. 設計とは 変更コストを下げるために コードを整理整頓する 実践的な工夫
Anzeige