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

“A Philosophy of Software Design” を30分でざっと理解する / Understand roughly "Philosophy of Software Design" in 30 minutes

iwashi
April 15, 2022

“A Philosophy of Software Design” を30分でざっと理解する / Understand roughly "Philosophy of Software Design" in 30 minutes

NTT Communications の社内ランチ勉強会 (TechLunch) で講演した資料です。

iwashi

April 15, 2022
Tweet

More Decks by iwashi

Other Decks in Programming

Transcript

  1. “A Philosophy of Software Design”
    を30分でざっと理解する
    2022/4/15
    NTT Communications 社内勉強会 (TechLunch #143)
    岩瀬 / @iwashi86
    書籍名が長いので、以降 APoSD と書きます
    Understand roughly "Philosophy of Software Design" in 30 minutes
    https://unsplash.com/photos/DuHKoV44prg

    View Slide

  2. Stanford大学のJOHN教授により執筆
    2

    View Slide

  3. 今日のゴール地点
    ● APoSD にかかれている内容をざっと知って
    日々の開発に活かせる気分になる
    ○ 人によっては、「おれ/わたしは今まで何てことを…」となる
    ● 詳細が知りたくなって買っている
    ○ Comの人は特に “学びシェア”施策 を使って
    安価でGETして、学びを社内に共有している
    ○ むしろTalk中にポチっている
    3

    View Slide

  4. ゴール目指して話すこと
    ● 書籍の概要: 全22章から20章のトピックをざっくり
    ● 注意点・免責
    ○ 中身の詳細は話さないので、続きは書籍で
    ○ スライド内文言は、わかりやすさ重視で意訳
    ■ 正確性は書籍を参照のこと
    ○ (書籍にも記載があるが) 筆者の経験ベースの書籍であり
    議論を呼ぶ箇所がある (Uncle Bob本とバッティングなど)
    4

    View Slide

  5. 本題
    5

    View Slide

  6. 目次
    6
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters (省略)
    22. Conclusion (省略)

    View Slide

  7. 目次
    7
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  8. 書籍の使い方
    ● 書籍の内容はやや抽象的
    ● もっとも良い使い方は、コードレビューでの併用
    ○ “APoSDの10章にある例外設計を考えると
    ここでは例外を送出するより、
    別のアプローチはどうでしょうか?” ※
    ※このコメントは書籍には存在せず、例として作成
    Chap 1
    8

    View Slide

  9. 目次
    9
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  10. 複雑性!複雑性!複雑性!
    ● 書籍ではひたすら
     「どうやって複雑性」と戦うか
    が述べられている
    ● 複雑とは
    ○ ソフトウェアシステムの構造に関するもの
    ○ システムの理解・修正を難しくするもの
    ○ 複雑さを決めるのは、not 書き手 but 読み手
    ● どんなに大規模でも、理解が容易で修正が簡単なら、複雑ではなく単純
    Chap 2
    10

    View Slide

  11. 複雑性で何が起こるのか?
    1. 変更の増大 (Change Amplification)
    ○ 例: 一見単純に見えるのに、変更箇所が多い
    2. 認知的負荷 (Cognitive Load)
    ○ 例: 多くのAPI、グローバル変数、モジュール依存関係
    3. 未知の増加 (Unknown Unknowns)
    ○ あるタスクの完了のために、何を変更すればいいかわからない
    ○ 3つのうち、これが最悪。変更を加えてバグが出るまでわからないため
    Chap 2
    11

    View Slide

  12. Chap 2
    “One of the most important goals of good design is
    for a system to be obvious.”
    優れた設計の最も重要な目標の1つは
    システムが明白であることだ
    Ousterhout, John K. . A Philosophy of Software Design, 2nd Edition (p. 9).
    Yaknyam Press. Kindle Edition.
    12

    View Slide

  13. 何が複雑性を生み出すのか
    ● 依存性 (Dependency)
    ○ 単独で理解・修正できない状態
    ○ 例: ネットワークプロトコルにて送信側を変更したら
    受信側を変更しないといけない
    ● 不明瞭性 (Obscurity)
    ○ 例: 一般的すぎる変数名 “time”
    ■ ドキュメントに単位などの記載がなければ
    コードを読み解かないとわからない
    Chap 2
    13

    View Slide

  14. 複雑性への立ち向かい方
    ● 複雑性の排除
    ○ 例: 特別なケースの排除
    ● 複雑性の隠蔽(カプセル化)
    ○ 例: 難解な部分を理解しなくても、使える
    ■ ファイルシステムとか
    Chap 2
    14

    View Slide

  15. 複雑性はちりつも (incremental)
    ● 1つの致命的なミスが生み出すわけではなく
    小さな塊が積み重なって起きる
    Chap 2
    15

    View Slide

  16. 目次
    16
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  17. 戦略(Strategic) vs 戦術(Tactical)
    ● 戦術(tactical)
    ○ とりあえず動けば良いというアプローチ
    ○ リファクタリングするより、次の機能を作るのが大事
    ○ Tactical Tornade
    ■ 戦術アプローチを極限まで追求するやつが組織には1人いる
    ● めちゃくちゃ早いので経営からは評価される
    ■ だけど残るのは破壊の軌跡
    ■ 本当の英雄は、破壊を抑止・修正するので進捗が遅く見える
    Chap 3
    17

    View Slide

  18. 戦略(Strategic) vs 戦術(Tactical)
    ● 戦略(strategic)
    ○ 重要なのは長期目線でのスピードアップ
    ● 10-20%の開発時間を投資すべき; 数ヶ月で回収できるだろう
    Chap 3
    18

    View Slide

  19. 目次
    19
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  20. モジュール
    ● 複雑性対処のための1つは、複雑性の隠蔽
    ○ その方法の1つがモジュールに分解すること
    ■ クラス、サブシステム、サービス、etc…
    ○ インターフェースと実装の分離
    ■ B-Treeのユーザは、挿入・削除の方法がわかればいい
    ■ バランシングするロジック詳細を
    ユーザは知らなくてもいい
    Chap 4
    20

    View Slide

  21. Module Should Be Deep
    ● 優れたモジュールは強力な機能とシンプルなIFを併せ持つ
    ○ APoSDではこれを「Deep Module」と呼ぶ
    Chap 4
    21

    View Slide

  22. Deep Module の素晴らしい例
    ● UnixにおけるファイルI/O
    ● 利用者が気にしなくていいことの例
    ○ ディスク上のファイル表現方法
    ○ ファイルアクセスにおける割り込みハンドラ
    ○ メモリキャッシュによるディスクアクセスの効率化 など
    Chap 4
    22

    View Slide

  23. Shallow Module で駄目な例
    Chap 4
    ● 提供機能に対してIFが複雑なのがShallow Module
    23

    View Slide

  24. Classitis
    Chap 4
    ● 小さく、浅いクラスを大量に作ること
    ● 顕著な例
    補足) この辺、Clean Code 第10章 とバッティング 24

    View Slide

  25. 目次
    25
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  26. 情報隠蔽 と 情報漏れ
    Chap 5
    ● 情報隠蔽: Deep Moduleは
    ○ IFをシンプルにすることで複雑さを隠蔽する
    ○ モジュール以外に依存関係をなくすことで進化を容易に
    ■ 例: TCP Protocol の実装が変わっても、上位アプリは変更不要
    ● 情報漏れ
    ○ ある設計変更が複数のモジュールに波及する
    ○ 例: 時間的分解
    ■ ファイル読み込み -> 変更 -> 書き出し を3つのクラスに分ける
    ■ 読み込みと書き出しは同じファイルフォーマットの知識が必要
    26

    View Slide

  27. 目次
    27
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  28. モジュールはある程度、汎用的にすべき
    Chap 6
    ● モジュール設計における判断
    ○ 特化させるか?汎用的にするか?どっち?
    ● 著者の経験上では、ある程度汎用的にするがオススメ
    ○ なぜならばシンプルで深いIFを実現できるため
    (参考: 書籍では、テキストエディタのコード例で説明あるので具体例はそちらで)
    28

    View Slide

  29. 目次
    29
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  30. 異なるレイヤでは、異なる抽象化をする
    Chap 7
    ● 異なる抽象化の例:ネットワーク・プロトコル
    ○ 最上位レイヤではバイトストリームの送受信
    ○ 下レイヤではベストエフォートで
    パケット分割して転送を実現するレイヤがある
    ■ パケットロスや、out-of-order に対応したりしなかったり
    30

    View Slide

  31. パススルーメソッドは同じレイヤで同じ抽象化した例
    Chap 7
    31
    ● ほぼ同じシグネチャを使っているShallowな例

    View Slide

  32. Decorator Pattern はどう?
    Chap 7
    ● 前述のJava I/Oの例がDecoratorパターン
    ○ 基本はオススメしない
    ● なぜならば、Shallow になりがちであるため
    ○ わずかな新機能のために大量のパススルーメソッドを使う
    ● じゃあどうする?
    ○ 新しい機能をベースクラスに追加する、
    独立したクラスにするなど
    32

    View Slide

  33. パススルー変数
    Chap 7
    cert がパススルー変数
    中間メソッドは使わないのに、中間メソッ
    ドが意識しないといけないので、認知負
    荷を増大させる = 複雑性の増大
    対策としては、context オブジェクトに詰
    め込む など (最高な解ではない)
    33
    main(argc, argv)

    m1(... cert, …)

    m2(... cert, …)

    m3(... cert, …) {
    openSocket(cert, …)
    }

    View Slide

  34. 目次
    34
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  35. 複雑性を下位におしやる
    Chap 8
    ● Q: どうしても避けられない複雑なパーツは
    ○ モジュール内部で隠蔽するべきか?
    ○ モジュールの利用者に処理させるべきか?
    ● A: 複雑さがモジュール提供機能と関連するなら
    モジュール内部で対応すべき
    35

    View Slide

  36. 設定パラメータの例
    Chap 8
    ● 設定パラメータは複雑を増大させる
    ○ キャッシュサイズはいくつにする?
    ○ リクエストのリトライ回数は?
    ● 多くの場合、ユーザーや管理者が正しい値を設定するのは困難
    ● 可能ならば、システム側で自動設定すべき
    ○ 例: リクエストの応答時間で再試行間隔を自動設定
    36

    View Slide

  37. 目次
    37
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  38. 同じとこに実装する? or 分けて実装する?
    Chap 9
    ● 重要なのは複雑性の軽減
    ● 細分化すればするほど
    ○ すべてのパーツの把握が困難に
    ○ パーツをつなぎ合わせるコードが増える
    ● パーツが本当に独立しているのであれば分割は良いこと
    ○ 開発者は1つのコンポーネントに集中できる
    38

    View Slide

  39. 分割有無の指針
    Chap 9
    ● 情報が共有される場合はまとめる
    ○ 例: HTTPリクエストの読み込みと解析
    ■ Headerからサイズを解析しないと、リクエスト全体の長さがわからず読み
    込めない
    ● IFをシンプルにできるならまとめる
    ○ Java I/O の例
    ■ FileInputStream と BufferedInputStream をあわせて
    バッファリングをデフォルト提供すればいい
    (バッファ無効はオプションとする)
    39

    View Slide

  40. ログのメソッドはほとんど Shallow。
    この場合は、クラス側を削除して、
    呼び出し側で書くだけでいい。
    Chap 9
    40

    View Slide

  41. “20行以上のメソッドは分割せよ!” ってホント?
    Chap 9
    ● メソッドの分割はIFの追加になるため複雑さを増大させる
    ○ システム全体がシンプルになるなら
    メソッドは分割すべきではない
    ● メソッド分割において
    ○ 子メソッドを読む人は親メソッドについて知らなくていい
    ○ 親メソッドを読む人は子メソッドの実装を知らなくていい
    41

    View Slide

  42. 目次
    42
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  43. 例外をそもそもなくす
    Chap 10
    ● 例外は複雑さを増大させる
    ○ 正常コードより本質的に書くのが難しい
    ○ 例外処理はさらなる例外を引き起こす
    ■ パケットロスによる再送による重複処理など
    ○ 例外処理コードの動作確認は難しい
    ● そもそも例外を使うべきかどうか考えたほうが良い
    43

    View Slide

  44. Tcl での設計ミスの例
    Chap 10
    ● unset という変数削除コマンドを設計した
    ○ 変数が存在しない場合は例外を投げる
    ○ 存在しない変数を削除するんだからバグだろうというアイデア
    ● unsetの用法は、何らかの操作で中断された状態をクリーンアップすること
    ○ 開発者にとって簡単なのは、可能性があるものをまるっとunset
    ● 結果、開発者は unset を全部 catch して無視するようになった
    44

    View Slide

  45. Tcl unset でどうすべきだったか?
    Chap 10
    ● そもそも処理すべき例外がないようにAPIを設計する
    ● 未知の変数の削除が要求されたら、「何もしないでReturn」する
    ○ どうせ開発者にとって必要な仕事は終わっているので
    45

    View Slide

  46. substringの例
    Chap 10
    ● Java の substring は begin > end だと例外を投げる
    ● Pythonだと slicing だと空の結果を返す
    46

    View Slide

  47. その他の例外対応
    Chap 10
    ● 例外をマスクする
    ○ 例: TCP再送により、パケット損失を気づかないように
    ● 例外の集約
    ● 診断に必要な情報を出力して、単にクラッシュする
    ○ 例: メモリ不足エラー。メモリ枯渇をアプリケーションが見つけても、大してやれ
    ることがない。
    47

    View Slide

  48. 目次
    48
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  49. Design it Twice
    Chap 11
    ● ソフトウェアの設計はそもそも難しい
    ● 例:テキストエディアの実装
    ○ 行指向?
    ○ キャラクター指向?
    ○ 文字列指向?
    ● オプションを複数設計して、長所・短所をリストアップして
    選んだほうが上手くいくことが多い
    49

    View Slide

  50. 目次
    50
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  51. なぜコメントを書くのか?
    Chap 12
    ● コメント・ドキュメントには抽象化という役割がある
    ● コメントを書かない4つの言い訳
    1. Good Code is self-documenting
    2. コメントを書く時間がない
    3. コメントが古くなってむしろミスリード
    4. これまで見てきたコメントは無価値だった
    51

    View Slide

  52. 1. Good Code is self-documenting
    Chap 12
    ● 良いコードなら、コメントはいらないでしょ というアイデア
    ○ 著者いわく「アイスクリームは健康に良い」という噂と同じぐらい神話
    ● クラスのIFは、型や変数などのシグネチャ以外を表現できない
    ○ メソッドの動作や、結果の意味、設計の決定根拠など
    コードだけでは表現できないものは多い
    ● そもそもコメントは抽象化の基本
    ○ 抽象化の目的は複雑さの隠蔽
    52

    View Slide

  53. 2. コメントを書く時間がない
    Chap 12
    ● ソフトウェアプロジェクトの多くは時間に追われている
    ○ 新機能の開発が優先され、
    ドキュメントの優先度が下がるとドキュメントがない状態につながる
    53

    View Slide

  54. 2. コメントを書く時間がない
    Chap 12
    ● ソフトウェアプロジェクトの多くは時間に追われている
    ○ 新機能の開発が優先され、
    ドキュメントの優先度が下がるとドキュメントがない状態につながる
    ● だが良いコメントは保守性に大きな違いをもたらす
    ○ コメント執筆に多くの時間を費やす必要はなく、コストはすぐ相殺可能
    54

    View Slide

  55. 3. コメントが古くなってむしろミスリード
    Chap 12
    ● コメントは古くなるが、実際には大きな問題ではない
    ○ ドキュメントを最新化するために、多大な労力は不要
    ● ドキュメントの大きな変更は、大きなコードの変更があるときだけ
    ○ Tips: コードの変更時にできるだけコメントを簡単に直せるように
    コードとドキュメントを近くに置くとよい
    55

    View Slide

  56. 4. これまで見てきたコメントは無価値だった
    Chap 12
    ● ソフトウェア開発者ならすべからく経験がある
    ● ただ幸いなことに、”良い” コメントでないだけ
    ⇒ しっかりしたドキュメントを書く方法を知れば対処可能
    56

    View Slide

  57. 目次
    57
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  58. 原則: コードから明らかでないことをコメントに書く
    Chap 13
    ● コメントはシンプルで上位の視点を与えてくれる
    ○ “このメソッドを呼び出した後、ネットワークトラフィックは
    毎秒 maxBandwidth に制限される”
    58

    View Slide

  59. 良いコメントを書くために
    Chap 13
    ● 規約を選ぶ
    ○ 何をコメントするのか?
    ○ どんな形式で書くのか?(言語にあわせる)
    ● コードと同じことを書かない
    シグネチャと同じ単語をコメントで書いている場合に注意
    ● 良い例
    良いコメントセクションは
    長いので続きは書籍で
    59

    View Slide

  60. 目次
    60
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  61. 命名
    Chap 14
    ● 良い名前は可読性を高める
    ● 一方で悪い名前は、複雑さ・曖昧さにより誤解・バグを生み出す
    ○ 例: block
    ■ ディスク上の物理的なブロックの番号
    ■ 論理的なブロックの番号
    ○ 読み手はどちらかに思い込んで読むので、デバッグが困難に
    ○ fileBlock と diskBlock と分けていれば発生しなかった
    61

    View Slide

  62. 良い名前 と 悪い名前
    Chap 14
    ● 良い名前は「正確性」と「一貫性」の2つの性質がある
    ○ 一貫性については前頁のdiskで重要性がわかる
    62

    View Slide

  63. 良い名前 と 悪い名前
    Chap 14
    ● 良い名前は「正確性」と「一貫性」の2つの性質がある
    ○ 一貫性については前頁のdiskで重要性がわかる
    ● 悪い名前で多いのは「一般的すぎる」 or 「曖昧すぎる」こと
    ○ getCount()
    ■ 何のカウントかわからないので、もっと明確化すべき
    ○ blinkStatus = true;
    カーソルが見えるときに可視化する変数としてだが、
    statusという名前はBoolean値としては曖昧すぎる名前である
    ■ たとえば、cursorVisible = true; ならわかりやすい
    63

    View Slide

  64. 目次
    64
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  65. 実装する前にコメントを書く(コメントを設計プロセスに組み込む)
    Chap 15
    ● よくあるパターン
    ○ コーディングとユニットテスト書いた
    ⇒ 最後にドキュメントを書く ⇒ 実際は書かない
    ● なぜ書かないのか? と質問すると
     ⇒ まだコードが変化しているから ⇒ これは次頁の悲劇を招く
    65

    View Slide

  66. 一度、コメントを書かずに遅らせると…
    Chap 15
    コードが安定してから
    コメントを書こう
    66

    View Slide

  67. 一度、コメントを書かずに遅らせると…
    Chap 15
    コードが安定してから
    コメントを書こう
    コードが安定した頃に
    はコードの量も膨大に

    67

    View Slide

  68. 一度、コメントを書かずに遅らせると…
    Chap 15
    コードが安定してから
    コメントを書こう
    ドキュメントを書くという
    タスクが肥大化
    (しかもコメントに書くべき内容
    を覚えてない)
    コードが安定した頃に
    はコードの量も膨大に

    68

    View Slide

  69. 一度、コメントを書かずに遅らせると…
    Chap 15
    コードが安定してから
    コメントを書こう
    ドキュメントを書くという
    タスクが肥大化
    (しかもコメントに書くべき内容
    を覚えてない)
    コードが安定した頃に
    はコードの量も膨大に

    っは!先に進んでバグ
    修正したり、新機能実
    装のが合理的では…
    (という逃避)
    69

    View Slide

  70. Comment First Process
    Chap 15
    ● 次の順でコメントを書いていく
    a. 新しいクラスではIFのコメントを書く
    b. 次に重要な Public メソッド のコメントとシグネチャを書く
    c. メソッド本体を実装する
    d. 実装中に追加メソッドや変数の必要性に気づいたら
    先にコメントから書いていく
    70

    View Slide

  71. 目次
    71
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  72. 既存コードの保守・メンテナンスにおいて…
    Chap 16
    ● 戦略的であり続ける
    ○ 通常、開発者が既存コードに手をいれる場合は戦術的になる
    「タスクを完了させるための最小な変更は何だろう?」
    72

    View Slide

  73. 既存コードの保守・メンテナンスにおいて…
    Chap 16
    ● 戦略的であり続ける
    ○ 通常、開発者が既存コードに手をいれる場合は戦術的になる
    「タスクを完了させるための最小な変更は何だろう?」
    ● 商用コードでは時間との戦いから、理想と現実で相反することがある
    ○ 正しい方法でリファクタすれば3ヶ月、素早くDirtyな方法なら2時間
    ○ 妥協にはできるだけ抵抗すべき
    ■ もし3ヶ月の変更にて、2-3日で完了できる大体があるなら…?
    73

    View Slide

  74. コメントをコードの近くに置く
    Chap 16
    ● 既存のコードを変更すると、コメントの一部が無効になることがある
    ○ ここでコメントを更新しないと、不正確なコメントが残る
    ○ 不正確なコメントは読み手をイライラさせ、
    かつ多い場合にはコメントを信用しなくなる
    74

    View Slide

  75. コメントをコードの近くに置く
    Chap 16
    ● 既存のコードを変更すると、コメントの一部が無効になることがある
    ○ ここでコメントを更新しないと、不正確なコメントが残る
    ○ 不正確なコメントは読み手をイライラさせ、
    かつ多い場合にはコメントを信用しなくなる
    ● 防止するために
    ○ コードとコメントを近くに配置しておく(気づきやすくなる)
    ○ 実装に対するコメントでは、メソッド冒頭にまとめて書かない
    ■ 例: 3つのフェーズがあるメソッドなら、
    1フェーズごとに個別コメントを書く
    75

    View Slide

  76. コメントはコミットログではなくコードに書く
    Chap 16
    ● コミットメッセージはリポジトリ内で検索可能
    ○ ただ、実際に確実に検索されるわけではない
    ○ 検索できたとしても、探し出すのは難しい
    ● 開発者が最も目にする可能性の高い場所にドキュメントを配置すべき
    76

    View Slide

  77. 目次
    77
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  78. 一貫性
    Chap 17
    ● 一貫性は複雑性の低減に寄与する
    ● では、どうやって一貫性を確保するか?
    ○ ドキュメント化する
    ■ たとえばコーディング規約などを書く
    ○ 規約が強制されるように仕組み化して実行する
    ■ コミット前に自動的にlintする
    ○ 郷に入っては郷に従う
    ■ 「良いアイデアを持ってる」からといって
    矛盾を起こして良いではない
    ■ 多くの場合、一貫性の価値が上回る
    78

    View Slide

  79. 目次
    79
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  80. コードは理解しやすくあるべき
    Chap 18
    ● “理解しやすさ” は読み手が判断する
    ○ ∴ コードの理解しやすさを判断する良い機会はコードレビュー
    80

    View Slide

  81. コードは理解しやすくあるべき
    Chap 18
    ● “理解しやすさ” は読み手が判断する
    ○ ∴ コードの理解しやすさを判断する良い機会はコードレビュー
    ● 理解しやすさを高める汎用テクニック
    ○ コードには適切な空白を入れておく
    ○ イベントドリブンなコードには
    ハンドラが発火するタイミングをコメントで書いておく など
    ○ (書籍には他にもいくつかテクニックの記載あり)
    81

    View Slide

  82. 目次
    82
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  83. ソフトウェアトレンド
    Chap 19
    ● OOP と 継承
    ● アジャイル開発
    ● ユニットテスト
    ● TDD
    ● デザインパターン
    ○ 最大のリスクは過剰適応
    ● getter & setter
    ○ IFを乱雑にする要因になるので、できるだけ避けたほうが良い
    83

    View Slide

  84. 目次
    84
    1. Introduction
    2. The Nature of Complexity
    3. Working Code isn’t Enough
    4. Modules Should Be Deep
    5. Information Hiding (and Leakage)
    6. General-Purpose Modules are Deeper
    7. Different Layer, Different Abstraction
    8. Pull Complexity Downwards
    9. Better Together Or Better Apart?
    10. Define Errors Out Of Existence
    11. Design it Twice
    12. Why Write Comments? The Four Excuses
    13. Comments Should Describe Things
    That Aren’t Obvious From The Code
    14. Choosing Names
    15. Write The Comments First
    16. Modifying Existing Code
    17. Consistency
    18. Code Should Be Obvious
    19. Software Trends
    20. Designing for Performance
    21. Decide What Matters
    22. Conclusion

    View Slide

  85. パフォーマンス向けの設計
    Chap 20
    ● どの程度、性能を気にすべきか?
    ○ すべてのコードを最高速度に最適化すべき?
    ○ 性能を完全に無視して書いてよい?
    ● 最適なアプローチは、性能に関する基本的な知識を用いて
    「自然に性能が出て」「クリーンでシンプル」なデザインを選ぶ
    ○ そのために、何がコストが高いか知っておく
    ■ 例: 二次記憶のI/Oでのレイテンシや、ネットワークのレイテンシ
    ● 修正する前に計測する
    85

    View Slide

  86. おしまい
    興味を持ったら詳細は是非書籍にて!
    86

    View Slide