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
  2. Stanford大学のJOHN教授により執筆 2

  3. 今日のゴール地点 • APoSD にかかれている内容をざっと知って 日々の開発に活かせる気分になる ◦ 人によっては、「おれ/わたしは今まで何てことを…」となる • 詳細が知りたくなって買っている ◦

    Comの人は特に “学びシェア”施策 を使って 安価でGETして、学びを社内に共有している ◦ むしろTalk中にポチっている 3
  4. ゴール目指して話すこと • 書籍の概要: 全22章から20章のトピックをざっくり • 注意点・免責 ◦ 中身の詳細は話さないので、続きは書籍で ◦ スライド内文言は、わかりやすさ重視で意訳

    ▪ 正確性は書籍を参照のこと ◦ (書籍にも記載があるが) 筆者の経験ベースの書籍であり 議論を呼ぶ箇所がある (Uncle Bob本とバッティングなど) 4
  5. 本題 5

  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 (省略)
  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
  8. 書籍の使い方 • 書籍の内容はやや抽象的 • もっとも良い使い方は、コードレビューでの併用 ◦ “APoSDの10章にある例外設計を考えると ここでは例外を送出するより、 別のアプローチはどうでしょうか?” ※

    ※このコメントは書籍には存在せず、例として作成 Chap 1 8
  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
  10. 複雑性!複雑性!複雑性! • 書籍ではひたすら  「どうやって複雑性」と戦うか が述べられている • 複雑とは ◦ ソフトウェアシステムの構造に関するもの ◦

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

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

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

    難解な部分を理解しなくても、使える ▪ ファイルシステムとか Chap 2 14
  15. 複雑性はちりつも (incremental) • 1つの致命的なミスが生み出すわけではなく 小さな塊が積み重なって起きる Chap 2 15

  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
  17. 戦略(Strategic) vs 戦術(Tactical) • 戦術(tactical) ◦ とりあえず動けば良いというアプローチ ◦ リファクタリングするより、次の機能を作るのが大事 ◦

    Tactical Tornade ▪ 戦術アプローチを極限まで追求するやつが組織には1人いる • めちゃくちゃ早いので経営からは評価される ▪ だけど残るのは破壊の軌跡 ▪ 本当の英雄は、破壊を抑止・修正するので進捗が遅く見える Chap 3 17
  18. 戦略(Strategic) vs 戦術(Tactical) • 戦略(strategic) ◦ 重要なのは長期目線でのスピードアップ • 10-20%の開発時間を投資すべき; 数ヶ月で回収できるだろう

    Chap 3 18
  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
  20. モジュール • 複雑性対処のための1つは、複雑性の隠蔽 ◦ その方法の1つがモジュールに分解すること ▪ クラス、サブシステム、サービス、etc… ◦ インターフェースと実装の分離 ▪

    B-Treeのユーザは、挿入・削除の方法がわかればいい ▪ バランシングするロジック詳細を ユーザは知らなくてもいい Chap 4 20
  21. Module Should Be Deep • 優れたモジュールは強力な機能とシンプルなIFを併せ持つ ◦ APoSDではこれを「Deep Module」と呼ぶ Chap

    4 21
  22. Deep Module の素晴らしい例 • UnixにおけるファイルI/O • 利用者が気にしなくていいことの例 ◦ ディスク上のファイル表現方法 ◦

    ファイルアクセスにおける割り込みハンドラ ◦ メモリキャッシュによるディスクアクセスの効率化 など Chap 4 22
  23. Shallow Module で駄目な例 Chap 4 • 提供機能に対してIFが複雑なのがShallow Module 23

  24. Classitis Chap 4 • 小さく、浅いクラスを大量に作ること • 顕著な例 補足) この辺、Clean Code

    第10章 とバッティング 24
  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
  26. 情報隠蔽 と 情報漏れ Chap 5 • 情報隠蔽: Deep Moduleは ◦

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

    なぜならばシンプルで深いIFを実現できるため (参考: 書籍では、テキストエディタのコード例で説明あるので具体例はそちらで) 28
  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
  30. 異なるレイヤでは、異なる抽象化をする Chap 7 • 異なる抽象化の例:ネットワーク・プロトコル ◦ 最上位レイヤではバイトストリームの送受信 ◦ 下レイヤではベストエフォートで パケット分割して転送を実現するレイヤがある

    ▪ パケットロスや、out-of-order に対応したりしなかったり 30
  31. パススルーメソッドは同じレイヤで同じ抽象化した例 Chap 7 31 • ほぼ同じシグネチャを使っているShallowな例

  32. Decorator Pattern はどう? Chap 7 • 前述のJava I/Oの例がDecoratorパターン ◦ 基本はオススメしない

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

    対策としては、context オブジェクトに詰 め込む など (最高な解ではない) 33 main(argc, argv) ↓ m1(... cert, …) ↓ m2(... cert, …) ↓ m3(... cert, …) { openSocket(cert, …) }
  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
  35. 複雑性を下位におしやる Chap 8 • Q: どうしても避けられない複雑なパーツは ◦ モジュール内部で隠蔽するべきか? ◦ モジュールの利用者に処理させるべきか?

    • A: 複雑さがモジュール提供機能と関連するなら モジュール内部で対応すべき 35
  36. 設定パラメータの例 Chap 8 • 設定パラメータは複雑を増大させる ◦ キャッシュサイズはいくつにする? ◦ リクエストのリトライ回数は? •

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

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

    込めない • IFをシンプルにできるならまとめる ◦ Java I/O の例 ▪ FileInputStream と BufferedInputStream をあわせて バッファリングをデフォルト提供すればいい (バッファ無効はオプションとする) 39
  40. ログのメソッドはほとんど Shallow。 この場合は、クラス側を削除して、 呼び出し側で書くだけでいい。 Chap 9 40

  41. “20行以上のメソッドは分割せよ!” ってホント? Chap 9 • メソッドの分割はIFの追加になるため複雑さを増大させる ◦ システム全体がシンプルになるなら メソッドは分割すべきではない •

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

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

    存在しない変数を削除するんだからバグだろうというアイデア • unsetの用法は、何らかの操作で中断された状態をクリーンアップすること ◦ 開発者にとって簡単なのは、可能性があるものをまるっとunset • 結果、開発者は unset を全部 catch して無視するようになった 44
  45. Tcl unset でどうすべきだったか? Chap 10 • そもそも処理すべき例外がないようにAPIを設計する • 未知の変数の削除が要求されたら、「何もしないでReturn」する ◦

    どうせ開発者にとって必要な仕事は終わっているので 45
  46. substringの例 Chap 10 • Java の substring は begin >

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

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

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

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

    著者いわく「アイスクリームは健康に良い」という噂と同じぐらい神話 • クラスのIFは、型や変数などのシグネチャ以外を表現できない ◦ メソッドの動作や、結果の意味、設計の決定根拠など コードだけでは表現できないものは多い • そもそもコメントは抽象化の基本 ◦ 抽象化の目的は複雑さの隠蔽 52
  53. 2. コメントを書く時間がない Chap 12 • ソフトウェアプロジェクトの多くは時間に追われている ◦ 新機能の開発が優先され、 ドキュメントの優先度が下がるとドキュメントがない状態につながる 53

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

    だが良いコメントは保守性に大きな違いをもたらす ◦ コメント執筆に多くの時間を費やす必要はなく、コストはすぐ相殺可能 54
  55. 3. コメントが古くなってむしろミスリード Chap 12 • コメントは古くなるが、実際には大きな問題ではない ◦ ドキュメントを最新化するために、多大な労力は不要 • ドキュメントの大きな変更は、大きなコードの変更があるときだけ

    ◦ Tips: コードの変更時にできるだけコメントを簡単に直せるように コードとドキュメントを近くに置くとよい 55
  56. 4. これまで見てきたコメントは無価値だった Chap 12 • ソフトウェア開発者ならすべからく経験がある • ただ幸いなことに、”良い” コメントでないだけ ⇒

    しっかりしたドキュメントを書く方法を知れば対処可能 56
  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
  58. 原則: コードから明らかでないことをコメントに書く Chap 13 • コメントはシンプルで上位の視点を与えてくれる ◦ “このメソッドを呼び出した後、ネットワークトラフィックは 毎秒 maxBandwidth

    に制限される” 58
  59. 良いコメントを書くために Chap 13 • 規約を選ぶ ◦ 何をコメントするのか? ◦ どんな形式で書くのか?(言語にあわせる) •

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

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

  63. 良い名前 と 悪い名前 Chap 14 • 良い名前は「正確性」と「一貫性」の2つの性質がある ◦ 一貫性については前頁のdiskで重要性がわかる • 悪い名前で多いのは「一般的すぎる」 or

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

    実際は書かない • なぜ書かないのか? と質問すると  ⇒ まだコードが変化しているから ⇒ これは次頁の悲劇を招く 65
  66. 一度、コメントを書かずに遅らせると… Chap 15 コードが安定してから コメントを書こう 66

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

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

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

    はコードの量も膨大に … っは!先に進んでバグ 修正したり、新機能実 装のが合理的では… (という逃避) 69
  70. Comment First Process Chap 15 • 次の順でコメントを書いていく a. 新しいクラスではIFのコメントを書く b.

    次に重要な Public メソッド のコメントとシグネチャを書く c. メソッド本体を実装する d. 実装中に追加メソッドや変数の必要性に気づいたら 先にコメントから書いていく 70
  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
  72. 既存コードの保守・メンテナンスにおいて… Chap 16 • 戦略的であり続ける ◦ 通常、開発者が既存コードに手をいれる場合は戦術的になる 「タスクを完了させるための最小な変更は何だろう?」 72

  73. 既存コードの保守・メンテナンスにおいて… Chap 16 • 戦略的であり続ける ◦ 通常、開発者が既存コードに手をいれる場合は戦術的になる 「タスクを完了させるための最小な変更は何だろう?」 • 商用コードでは時間との戦いから、理想と現実で相反することがある

    ◦ 正しい方法でリファクタすれば3ヶ月、素早くDirtyな方法なら2時間 ◦ 妥協にはできるだけ抵抗すべき ▪ もし3ヶ月の変更にて、2-3日で完了できる大体があるなら…? 73
  74. コメントをコードの近くに置く Chap 16 • 既存のコードを変更すると、コメントの一部が無効になることがある ◦ ここでコメントを更新しないと、不正確なコメントが残る ◦ 不正確なコメントは読み手をイライラさせ、 かつ多い場合にはコメントを信用しなくなる

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

    • 防止するために ◦ コードとコメントを近くに配置しておく(気づきやすくなる) ◦ 実装に対するコメントでは、メソッド冒頭にまとめて書かない ▪ 例: 3つのフェーズがあるメソッドなら、 1フェーズごとに個別コメントを書く 75
  76. コメントはコミットログではなくコードに書く Chap 16 • コミットメッセージはリポジトリ内で検索可能 ◦ ただ、実際に確実に検索されるわけではない ◦ 検索できたとしても、探し出すのは難しい •

    開発者が最も目にする可能性の高い場所にドキュメントを配置すべき 76
  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
  78. 一貫性 Chap 17 • 一貫性は複雑性の低減に寄与する • では、どうやって一貫性を確保するか? ◦ ドキュメント化する ▪

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

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

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

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

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