$30 off During Our Annual Pro Sale. View Details »

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

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

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. ソフトウェアを変更する理由(複合)
    • 事業の存続性の改善(存続優位・存続劣位)
    • 事業環境(社会経済・市場の競合・顧客の価値観)が変わる
    • 事業の遂行能力(組織・人材・仕事のやり方)を変える
    • 開発者の事業活動の理解が変わる
    • 開発者の設計能力が変わる
    • 利用できる技術の費用対効果が変わる(メモリ、帯域、…)
    2022/11/7 8

    View Slide

  9. ソフトウェアの変更が楽で安全であれば
    • 事業活動の変化のスピードを上げられる
    • 事業活動の変化のコストを下げられる
    • 開発者の成長の機会を増やせる
    • 開発者の学びと成長をソフトウェアに反映できる
    • 費用対効果の高い技術に移行できる
    2022/11/7 9

    View Slide

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

    View Slide

  11. 良い設計をするための
    知識と技能を習得する
    2022/11/7 11

    View Slide

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

    View Slide

  13. コードの不吉な臭い
    • 怪しげな名前(クラス名、パッケージ名、変数名)
    • 長いメソッド
    • 大きなクラス/大きなパッケージ
    • 可変性(ミュータブル, setter, 変数への再代入)
    • 重複(式、if文/switch文、for文/Streamメソッドチェイン)
    • データクラス(getter, setter)
    • 基本データ型の群れ(int, int, int, String, String, String )
    2022/11/7 13

    View Slide

  14. 良い形の習得
    値オブジェクト
    区分オブジェクト
    コレクションオブジェクト
    名前空間(パッケージ構造)
    2022/11/7 14

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  19. 「良い形」の背景にある考え方
    型(値の種類の分類)
    • 操作の集合として値の種類を定義する(金額、数量、日付、区分、コレクション)
    • データの抽象化
    カプセル化
    • データ操作とデータ表現を同じモジュールに凝集させる
    • クラス構文(Java, C# …)、メソッド構文(Rust, Go)
    契約プログラミング
    • クラス間のつなぎ方の約束
    • 事前条件:引数の型で制限する
    • 事後条件:メソッドの返す型で制限する
    • 不変条件:オブジェクトの状態を変更しないことを確約
    2022/11/7 19

    View Slide

  20. 分け方・集め方・つなぎ方の
    知識と技能の習得
    2022/11/7 20

    View Slide

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

    View Slide

  22. 分け方・集め方・つなぎ方を学ぶ
    コードレベルの原則とパターンの習得
    • クラス/パッケージの設計と実装、リファクタリング
    • テーブル/スキーマの設計と実装、リファクタリング
    • 通知・転送(API/メッセージング)の設計と実装、リファクタリング
    中範囲の原則とパターンの習得
    • 単一のアプリケーションのアーキテクチャの実装と運用・保守・改善
    広い範囲の原則とパターンの習得
    • 分散アーキテクチャの実装と運用・保守・改善
    2022/11/7 22

    View Slide

  23. 永続化クライアント
    @Repository
    JDBC Template
    SQLMapper
    通信クライアント
    @Component
    Rest Template
    JMS Template
    アクションの起動
    @Controller
    @RestController
    @MessageListener
    @Scheduled
    ビジネスアクションクラス
    計算判断の実行
    通知・依頼
    記録・参照
    @Service
    ビジネスルールクラス
    事業活動の決め事
    計算判断ロジックの
    宣言的な記述
    POJO
    単純
    複雑
    フレームワークで単純化
    フレームワークで単純化
    ドメインモデル
    中範囲の分け方・集め方・つなぎ方
    2022/11/7 23
    Java/Spring Bootの実装例
    使う
    単一のアプリケーション

    View Slide

  24. 広い範囲の分け方・集め方・つなぎ方
    2022/11/7 24
    ➢ アーキテクチャの分解
    ➢ 業務データの分解
    ➢ サービスの粒度
    ◆データの所有権
    ◆分散ワークフロー
    ◆トランザクショナルサーガ
    ◆コントラクト
    ◆分散分析データ
    分散アーキテクチャ

    View Slide

  25. まとめ
    2022/11/7 25

    View Slide

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

    View Slide

  27. ソフトウェアの変更が楽で安全であれば
    • 事業活動の変化のスピードを上げられる
    • 事業活動の変化のコストを下げられる
    • 開発者の成長の機会を増やせる
    • 開発者の学びと成長をソフトウェアに反映できる
    • 費用対効果の高い技術に移行できる
    2022/11/7 27

    View Slide

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

    View Slide