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

“A Philosophy of Software Design” を30分でざっと理解する ...

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
  2. ゴール目指して話すこと • 書籍の概要: 全22章から20章のトピックをざっくり • 注意点・免責 ◦ 中身の詳細は話さないので、続きは書籍で ◦ スライド内文言は、わかりやすさ重視で意訳

    ▪ 正確性は書籍を参照のこと ◦ (書籍にも記載があるが) 筆者の経験ベースの書籍であり 議論を呼ぶ箇所がある (Uncle Bob本とバッティングなど) 4
  3. 目次 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 (省略)
  4. 目次 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
  5. 目次 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
  6. 複雑性!複雑性!複雑性! • 書籍ではひたすら  「どうやって複雑性」と戦うか が述べられている • 複雑とは ◦ ソフトウェアシステムの構造に関するもの ◦

    システムの理解・修正を難しくするもの ◦ 複雑さを決めるのは、not 書き手 but 読み手 • どんなに大規模でも、理解が容易で修正が簡単なら、複雑ではなく単純 Chap 2 10
  7. 複雑性で何が起こるのか? 1. 変更の増大 (Change Amplification) ◦ 例: 一見単純に見えるのに、変更箇所が多い 2. 認知的負荷

    (Cognitive Load) ◦ 例: 多くのAPI、グローバル変数、モジュール依存関係 3. 未知の増加 (Unknown Unknowns) ◦ あるタスクの完了のために、何を変更すればいいかわからない ◦ 3つのうち、これが最悪。変更を加えてバグが出るまでわからないため Chap 2 11
  8. 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
  9. 何が複雑性を生み出すのか • 依存性 (Dependency) ◦ 単独で理解・修正できない状態 ◦ 例: ネットワークプロトコルにて送信側を変更したら 受信側を変更しないといけない

    • 不明瞭性 (Obscurity) ◦ 例: 一般的すぎる変数名 “time” ▪ ドキュメントに単位などの記載がなければ コードを読み解かないとわからない Chap 2 13
  10. 複雑性への立ち向かい方 • 複雑性の排除 ◦ 例: 特別なケースの排除 • 複雑性の隠蔽(カプセル化) ◦ 例:

    難解な部分を理解しなくても、使える ▪ ファイルシステムとか Chap 2 14
  11. 目次 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
  12. 戦略(Strategic) vs 戦術(Tactical) • 戦術(tactical) ◦ とりあえず動けば良いというアプローチ ◦ リファクタリングするより、次の機能を作るのが大事 ◦

    Tactical Tornade ▪ 戦術アプローチを極限まで追求するやつが組織には1人いる • めちゃくちゃ早いので経営からは評価される ▪ だけど残るのは破壊の軌跡 ▪ 本当の英雄は、破壊を抑止・修正するので進捗が遅く見える Chap 3 17
  13. 目次 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
  14. モジュール • 複雑性対処のための1つは、複雑性の隠蔽 ◦ その方法の1つがモジュールに分解すること ▪ クラス、サブシステム、サービス、etc… ◦ インターフェースと実装の分離 ▪

    B-Treeのユーザは、挿入・削除の方法がわかればいい ▪ バランシングするロジック詳細を ユーザは知らなくてもいい Chap 4 20
  15. Deep Module の素晴らしい例 • UnixにおけるファイルI/O • 利用者が気にしなくていいことの例 ◦ ディスク上のファイル表現方法 ◦

    ファイルアクセスにおける割り込みハンドラ ◦ メモリキャッシュによるディスクアクセスの効率化 など Chap 4 22
  16. 目次 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
  17. 情報隠蔽 と 情報漏れ Chap 5 • 情報隠蔽: Deep Moduleは ◦

    IFをシンプルにすることで複雑さを隠蔽する ◦ モジュール以外に依存関係をなくすことで進化を容易に ▪ 例: TCP Protocol の実装が変わっても、上位アプリは変更不要 • 情報漏れ ◦ ある設計変更が複数のモジュールに波及する ◦ 例: 時間的分解 ▪ ファイル読み込み -> 変更 -> 書き出し を3つのクラスに分ける ▪ 読み込みと書き出しは同じファイルフォーマットの知識が必要 26
  18. 目次 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
  19. モジュールはある程度、汎用的にすべき Chap 6 • モジュール設計における判断 ◦ 特化させるか?汎用的にするか?どっち? • 著者の経験上では、ある程度汎用的にするがオススメ ◦

    なぜならばシンプルで深いIFを実現できるため (参考: 書籍では、テキストエディタのコード例で説明あるので具体例はそちらで) 28
  20. 目次 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
  21. Decorator Pattern はどう? Chap 7 • 前述のJava I/Oの例がDecoratorパターン ◦ 基本はオススメしない

    • なぜならば、Shallow になりがちであるため ◦ わずかな新機能のために大量のパススルーメソッドを使う • じゃあどうする? ◦ 新しい機能をベースクラスに追加する、 独立したクラスにするなど 32
  22. パススルー変数 Chap 7 cert がパススルー変数 中間メソッドは使わないのに、中間メソッ ドが意識しないといけないので、認知負 荷を増大させる = 複雑性の増大

    対策としては、context オブジェクトに詰 め込む など (最高な解ではない) 33 main(argc, argv) ↓ m1(... cert, …) ↓ m2(... cert, …) ↓ m3(... cert, …) { openSocket(cert, …) }
  23. 目次 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
  24. 設定パラメータの例 Chap 8 • 設定パラメータは複雑を増大させる ◦ キャッシュサイズはいくつにする? ◦ リクエストのリトライ回数は? •

    多くの場合、ユーザーや管理者が正しい値を設定するのは困難 • 可能ならば、システム側で自動設定すべき ◦ 例: リクエストの応答時間で再試行間隔を自動設定 36
  25. 目次 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
  26. 同じとこに実装する? or 分けて実装する? Chap 9 • 重要なのは複雑性の軽減 • 細分化すればするほど ◦

    すべてのパーツの把握が困難に ◦ パーツをつなぎ合わせるコードが増える • パーツが本当に独立しているのであれば分割は良いこと ◦ 開発者は1つのコンポーネントに集中できる 38
  27. 分割有無の指針 Chap 9 • 情報が共有される場合はまとめる ◦ 例: HTTPリクエストの読み込みと解析 ▪ Headerからサイズを解析しないと、リクエスト全体の長さがわからず読み

    込めない • IFをシンプルにできるならまとめる ◦ Java I/O の例 ▪ FileInputStream と BufferedInputStream をあわせて バッファリングをデフォルト提供すればいい (バッファ無効はオプションとする) 39
  28. “20行以上のメソッドは分割せよ!” ってホント? Chap 9 • メソッドの分割はIFの追加になるため複雑さを増大させる ◦ システム全体がシンプルになるなら メソッドは分割すべきではない •

    メソッド分割において ◦ 子メソッドを読む人は親メソッドについて知らなくていい ◦ 親メソッドを読む人は子メソッドの実装を知らなくていい 41
  29. 目次 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
  30. 例外をそもそもなくす Chap 10 • 例外は複雑さを増大させる ◦ 正常コードより本質的に書くのが難しい ◦ 例外処理はさらなる例外を引き起こす ▪

    パケットロスによる再送による重複処理など ◦ 例外処理コードの動作確認は難しい • そもそも例外を使うべきかどうか考えたほうが良い 43
  31. Tcl での設計ミスの例 Chap 10 • unset という変数削除コマンドを設計した ◦ 変数が存在しない場合は例外を投げる ◦

    存在しない変数を削除するんだからバグだろうというアイデア • unsetの用法は、何らかの操作で中断された状態をクリーンアップすること ◦ 開発者にとって簡単なのは、可能性があるものをまるっとunset • 結果、開発者は unset を全部 catch して無視するようになった 44
  32. substringの例 Chap 10 • Java の substring は begin >

    end だと例外を投げる • Pythonだと slicing だと空の結果を返す 46
  33. その他の例外対応 Chap 10 • 例外をマスクする ◦ 例: TCP再送により、パケット損失を気づかないように • 例外の集約

    • 診断に必要な情報を出力して、単にクラッシュする ◦ 例: メモリ不足エラー。メモリ枯渇をアプリケーションが見つけても、大してやれ ることがない。 47
  34. 目次 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
  35. Design it Twice Chap 11 • ソフトウェアの設計はそもそも難しい • 例:テキストエディアの実装 ◦

    行指向? ◦ キャラクター指向? ◦ 文字列指向? • オプションを複数設計して、長所・短所をリストアップして 選んだほうが上手くいくことが多い 49
  36. 目次 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
  37. なぜコメントを書くのか? Chap 12 • コメント・ドキュメントには抽象化という役割がある • コメントを書かない4つの言い訳 1. Good Code

    is self-documenting 2. コメントを書く時間がない 3. コメントが古くなってむしろミスリード 4. これまで見てきたコメントは無価値だった 51
  38. 1. Good Code is self-documenting Chap 12 • 良いコードなら、コメントはいらないでしょ というアイデア ◦

    著者いわく「アイスクリームは健康に良い」という噂と同じぐらい神話 • クラスのIFは、型や変数などのシグネチャ以外を表現できない ◦ メソッドの動作や、結果の意味、設計の決定根拠など コードだけでは表現できないものは多い • そもそもコメントは抽象化の基本 ◦ 抽象化の目的は複雑さの隠蔽 52
  39. 目次 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
  40. 良いコメントを書くために Chap 13 • 規約を選ぶ ◦ 何をコメントするのか? ◦ どんな形式で書くのか?(言語にあわせる) •

    コードと同じことを書かない シグネチャと同じ単語をコメントで書いている場合に注意 • 良い例 良いコメントセクションは 長いので続きは書籍で 59
  41. 目次 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
  42. 命名 Chap 14 • 良い名前は可読性を高める • 一方で悪い名前は、複雑さ・曖昧さにより誤解・バグを生み出す ◦ 例: block

    ▪ ディスク上の物理的なブロックの番号 ▪ 論理的なブロックの番号 ◦ 読み手はどちらかに思い込んで読むので、デバッグが困難に ◦ fileBlock と diskBlock と分けていれば発生しなかった 61
  43. 良い名前 と 悪い名前 Chap 14 • 良い名前は「正確性」と「一貫性」の2つの性質がある ◦ 一貫性については前頁のdiskで重要性がわかる • 悪い名前で多いのは「一般的すぎる」 or

    「曖昧すぎる」こと ◦ getCount() ▪ 何のカウントかわからないので、もっと明確化すべき ◦ blinkStatus = true; カーソルが見えるときに可視化する変数としてだが、 statusという名前はBoolean値としては曖昧すぎる名前である ▪ たとえば、cursorVisible = true; ならわかりやすい 63
  44. 目次 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
  45. 実装する前にコメントを書く(コメントを設計プロセスに組み込む) Chap 15 • よくあるパターン ◦ コーディングとユニットテスト書いた ⇒ 最後にドキュメントを書く ⇒

    実際は書かない • なぜ書かないのか? と質問すると  ⇒ まだコードが変化しているから ⇒ これは次頁の悲劇を招く 65
  46. Comment First Process Chap 15 • 次の順でコメントを書いていく a. 新しいクラスではIFのコメントを書く b.

    次に重要な Public メソッド のコメントとシグネチャを書く c. メソッド本体を実装する d. 実装中に追加メソッドや変数の必要性に気づいたら 先にコメントから書いていく 70
  47. 目次 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
  48. コメントをコードの近くに置く Chap 16 • 既存のコードを変更すると、コメントの一部が無効になることがある ◦ ここでコメントを更新しないと、不正確なコメントが残る ◦ 不正確なコメントは読み手をイライラさせ、 かつ多い場合にはコメントを信用しなくなる

    • 防止するために ◦ コードとコメントを近くに配置しておく(気づきやすくなる) ◦ 実装に対するコメントでは、メソッド冒頭にまとめて書かない ▪ 例: 3つのフェーズがあるメソッドなら、 1フェーズごとに個別コメントを書く 75
  49. 目次 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
  50. 一貫性 Chap 17 • 一貫性は複雑性の低減に寄与する • では、どうやって一貫性を確保するか? ◦ ドキュメント化する ▪

    たとえばコーディング規約などを書く ◦ 規約が強制されるように仕組み化して実行する ▪ コミット前に自動的にlintする ◦ 郷に入っては郷に従う ▪ 「良いアイデアを持ってる」からといって 矛盾を起こして良いではない ▪ 多くの場合、一貫性の価値が上回る 78
  51. 目次 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
  52. コードは理解しやすくあるべき Chap 18 • “理解しやすさ” は読み手が判断する ◦ ∴ コードの理解しやすさを判断する良い機会はコードレビュー •

    理解しやすさを高める汎用テクニック ◦ コードには適切な空白を入れておく ◦ イベントドリブンなコードには ハンドラが発火するタイミングをコメントで書いておく など ◦ (書籍には他にもいくつかテクニックの記載あり) 81
  53. 目次 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
  54. ソフトウェアトレンド Chap 19 • OOP と 継承 • アジャイル開発 •

    ユニットテスト • TDD • デザインパターン ◦ 最大のリスクは過剰適応 • getter & setter ◦ IFを乱雑にする要因になるので、できるだけ避けたほうが良い 83
  55. 目次 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
  56. パフォーマンス向けの設計 Chap 20 • どの程度、性能を気にすべきか? ◦ すべてのコードを最高速度に最適化すべき? ◦ 性能を完全に無視して書いてよい? •

    最適なアプローチは、性能に関する基本的な知識を用いて 「自然に性能が出て」「クリーンでシンプル」なデザインを選ぶ ◦ そのために、何がコストが高いか知っておく ▪ 例: 二次記憶のI/Oでのレイテンシや、ネットワークのレイテンシ • 修正する前に計測する 85