Slide 1

Slide 1 text

“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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

本題 5

Slide 6

Slide 6 text

目次 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 (省略)

Slide 7

Slide 7 text

目次 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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

目次 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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

目次 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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

目次 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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

目次 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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

目次 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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

目次 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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

目次 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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

目次 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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

目次 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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

目次 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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

目次 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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

目次 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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

目次 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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

目次 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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

一度、コメントを書かずに遅らせると… Chap 15 コードが安定してから コメントを書こう ドキュメントを書くという タスクが肥大化 (しかもコメントに書くべき内容 を覚えてない) コードが安定した頃に はコードの量も膨大に … っは!先に進んでバグ 修正したり、新機能実 装のが合理的では… (という逃避) 69

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

目次 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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

目次 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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

目次 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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

目次 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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

目次 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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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