Upgrade to Pro — share decks privately, control downloads, hide ads and more …

良い設計と悪い設計の違い

 良い設計と悪い設計の違い

2022年11月7日(月)
「現場で役立つシステム設計の原則 - Forkwell Library #9」
発表資料

増田 亨
PRO

November 10, 2022
Tweet

More Decks by 増田 亨

Other Decks in Programming

Transcript

  1. 良い設計と悪い設計の違い 2022年11月7日 有限会社システム設計 増田 亨 Forkwell-Library #9

  2. 自己紹介 アプリケーション開発者 業務系アプリケーション ドメイン駆動設計/リファクタリング Java/Spring/IntelliJ IDEA/JIG 著書『現場で役立つシステム設計の原則』 ~変更を楽で安全にするオブジェクト指向の実践技法 技術者コミュニティ「現場から学ぶモデル駆動の設計」主催 2022/11/7

    2
  3. お話すること 1. 良い設計と悪い設計の違い 2. 良い設計が生み出す効果 3. 良い設計をするための知識と技能 2022/11/7 3

  4. 良い設計と悪い設計の違い 2022/11/7 4

  5. 良い設計は悪い設計より 変更が楽で安全である 2022/11/7 5

  6. 設計の良し悪しをどう判断するか 実際に変更しようとしてやっかいで危険であれば悪い設計 あらゆる箇所を実際に変更して良し悪しの評価はできない そこで 悪い設計のコードには特徴がある(不吉な臭い) そういう臭いをコードに持ち込まない考え方とやり方を習得する 2022/11/7 6

  7. 良い設計が生み出す効果 2022/11/7 7

  8. ソフトウェアを変更する理由(複合) • 事業の存続性の改善(存続優位・存続劣位) • 事業環境(社会経済・市場の競合・顧客の価値観)が変わる • 事業の遂行能力(組織・人材・仕事のやり方)を変える • 開発者の事業活動の理解が変わる •

    開発者の設計能力が変わる • 利用できる技術の費用対効果が変わる(メモリ、帯域、…) 2022/11/7 8
  9. ソフトウェアの変更が楽で安全であれば • 事業活動の変化のスピードを上げられる • 事業活動の変化のコストを下げられる • 開発者の成長の機会を増やせる • 開発者の学びと成長をソフトウェアに反映できる •

    費用対効果の高い技術に移行できる 2022/11/7 9
  10. ソフトウェアの変更がやっかいで危険になると • 事業活動の変化のスピードを落とす • 事業活動の変化のコストが増える • 開発者の成長の機会が減る • 開発者の学びと成長をソフトウェア開発に活かせない •

    費用対効果の悪い技術を使い続ける 2022/11/7 10
  11. 良い設計をするための 知識と技能を習得する 2022/11/7 11

  12. 良い設計をするための知識と技能 • コードの不吉な臭い(設計の良し悪しを判断する嗅覚) • 「良い形」の習得 • 「分け方・集め方・つなぎ方」の習得 2022/11/7 12

  13. コードの不吉な臭い • 怪しげな名前(クラス名、パッケージ名、変数名) • 長いメソッド • 大きなクラス/大きなパッケージ • 可変性(ミュータブル, setter,

    変数への再代入) • 重複(式、if文/switch文、for文/Streamメソッドチェイン) • データクラス(getter, setter) • 基本データ型の群れ(int, int, int, String, String, String ) 2022/11/7 13
  14. 良い形の習得 値オブジェクト 区分オブジェクト コレクションオブジェクト 名前空間(パッケージ構造) 2022/11/7 14

  15. 良い形:値オブジェクト • アプリケーションで扱う値の計算ロジックの置き場所 • 業務ルール(計算式など)に登場する値の名称 • 正しい値・正しい計算の詳細仕様をコードで記述 • 基本データ型の隠蔽 •

    不変性の徹底(値が異なれば別のオブジェクトを作る) 2022/11/7 15
  16. 良い形:区分オブジェクト • if文/switch文のコードの重複の防止 • 業務活動で起きる「場合」の構造と名前をコードに取り入れる • 表形式の業務ルールの表現(例:年齢別料金、時間帯割引) • 既存の区分を整理(排他的網羅に)→ 不必要な複雑さの解消

    2022/11/7 16
  17. 良い形:コレクションオブジェクト for文/Streamメソッドチェーンのコードの重複の防止 業務で関心のある対象の「集まり」の呼び方を名前にする • 出荷待ち一覧 要素の選択条件・値の集約方法の仕様化 • 優先出荷対象の抽出 • 商品別の出荷待ち数の集計

    2022/11/7 17
  18. 良い形:名前空間(パッケージ構造) • 最小要素(クラス=業務ルールを説明する基本語彙) • コンポーネント(クラスのグループ、業務ルールの種類) • サブドメイン(コンポーネントのグルーピング、業務領域) • ドメイン(サブドメインのグルーピング、事業領域) •

    業務知識を整理する構造 • 業務ルールを説明する用語の関連付けと一貫性の維持 2022/11/7 18
  19. 「良い形」の背景にある考え方 型(値の種類の分類) • 操作の集合として値の種類を定義する(金額、数量、日付、区分、コレクション) • データの抽象化 カプセル化 • データ操作とデータ表現を同じモジュールに凝集させる •

    クラス構文(Java, C# …)、メソッド構文(Rust, Go) 契約プログラミング • クラス間のつなぎ方の約束 • 事前条件:引数の型で制限する • 事後条件:メソッドの返す型で制限する • 不変条件:オブジェクトの状態を変更しないことを確約 2022/11/7 19
  20. 分け方・集め方・つなぎ方の 知識と技能の習得 2022/11/7 20

  21. 設計原則と設計パターン 原則とパターンは他人の経験知 自分の経験知にするために、手を動かして効果を実感する 変更がやっかいで危険なコードをリファクタリングした結果「なるほ ど」となることが多い あらゆる設計原則と設計パターンは 変更を楽で安全にする考え方とやり方の言語化 分け方・集め方・つなぎ方の考え方とやり方の言語化 2022/11/7 21

  22. 分け方・集め方・つなぎ方を学ぶ コードレベルの原則とパターンの習得 • クラス/パッケージの設計と実装、リファクタリング • テーブル/スキーマの設計と実装、リファクタリング • 通知・転送(API/メッセージング)の設計と実装、リファクタリング 中範囲の原則とパターンの習得 •

    単一のアプリケーションのアーキテクチャの実装と運用・保守・改善 広い範囲の原則とパターンの習得 • 分散アーキテクチャの実装と運用・保守・改善 2022/11/7 22
  23. 永続化クライアント @Repository JDBC Template SQLMapper 通信クライアント @Component Rest Template JMS

    Template アクションの起動 @Controller @RestController @MessageListener @Scheduled ビジネスアクションクラス 計算判断の実行 通知・依頼 記録・参照 @Service ビジネスルールクラス 事業活動の決め事 計算判断ロジックの 宣言的な記述 POJO 単純 複雑 フレームワークで単純化 フレームワークで単純化 ドメインモデル 中範囲の分け方・集め方・つなぎ方 2022/11/7 23 Java/Spring Bootの実装例 使う 単一のアプリケーション
  24. 広い範囲の分け方・集め方・つなぎ方 2022/11/7 24 ➢ アーキテクチャの分解 ➢ 業務データの分解 ➢ サービスの粒度 ◆データの所有権

    ◆分散ワークフロー ◆トランザクショナルサーガ ◆コントラクト ◆分散分析データ 分散アーキテクチャ
  25. まとめ 2022/11/7 25

  26. 良い設計は悪い設計より 変更が楽で安全である 2022/11/7 26

  27. ソフトウェアの変更が楽で安全であれば • 事業活動の変化のスピードを上げられる • 事業活動の変化のコストを下げられる • 開発者の成長の機会を増やせる • 開発者の学びと成長をソフトウェアに反映できる •

    費用対効果の高い技術に移行できる 2022/11/7 27
  28. 変更を楽で安全にする設計 それが開発者がやるべき仕事 私が実践している設計の考え方とやり方は、この価値観に基づいている 2022/11/7 28