A Philosophy of Software Design
Softwaredesign

A Philosophy of Software Design

John Ousterhout, 2021

Inhaltsverzeichnis des Buches

  • Preface
  • 1 Introduction
  • 1.1 How to use this book
  • 2 The Nature of Complexity
  • 2.1 Complexity defined
  • 2.2 Symptoms of complexity
  • 2.3 Causes of complexity
  • 2.4 Complexity is incremental
  • 2.5 Conclusion
  • 3 Working Code Isn’t Enough
  • 3.1 Tactical programming
  • 3.2 Strategic programming
  • 3.3 How much to invest?
  • 3.4 Startups and investment
  • 3.5 Conclusion
  • 4 Modules Should Be Deep
  • 4.1 Modular design
  • 4.2 What’s in an interface?
  • 4.3 Abstractions
  • 4.4 Deep modules
  • 4.5 Shallow modules
  • 4.6 Classitis
  • 4.7 Examples: Java and Unix I/O
  • 4.8 Conclusion
  • 5 Information Hiding (and Leakage)
  • 5.1 Information hiding
  • 5.2 Information leakage
  • 5.3 Temporal decomposition
  • 5.4 Example: HTTP server
  • 5.5 Example: too many classes
  • 5.6 Example: HTTP parameter handling
  • 5.7 Example: defaults in HTTP responses
  • 5.8 Information hiding within a class
  • 5.9 Taking it too far
  • 5.10 Conclusion
  • 6 General-Purpose Modules are Deeper
  • 6.1 Make classes somewhat general-purpose
  • 6.2 Example: storing text for an editor
  • 6.3 A more general-purpose API
  • 6.4 Generality leads to better information hiding
  • 6.5 Questions to ask yourself
  • 6.6 Push specialization upwards (and downwards!)
  • 6.7 Example: editor undo mechanism
  • 6.8 Eliminate special cases in code
  • 6.9 Conclusion
  • 7 Different Layer, Different Abstraction
  • 7.1 Pass-through methods
  • 7.2 When is interface duplication OK?
  • 7.3 Decorators
  • 7.4 Interface versus implementation
  • 7.5 Pass-through variables
  • 7.6 Conclusion
  • 8 Pull Complexity Downwards
  • 8.1 Example: editor text class
  • 8.2 Example: configuration parameters
  • 8.3 Taking it too far
  • 8.4 Conclusion
  • 9 Better Together Or Better Apart?
  • 9.1 Bring together if information is shared
  • 9.2 Bring together if it will simplify the interface
  • 9.3 Bring together to eliminate duplication
  • 9.4 Separate general-purpose and special-purpose code
  • 9.5 Example: insertion cursor and selection
  • 9.6 Example: separate class for logging
  • 9.7 Splitting and joining methods
  • 9.8 A different opinion: Clean Code
  • 9.9 Conclusion
  • 10 Define Errors Out Of Existence
  • 10.1 Why exceptions add complexity
  • 10.2 Too many exceptions
  • 10.3 Define errors out of existence
  • 10.4 Example: file deletion in Windows
  • 10.5 Example: Java substring method
  • 10.6 Mask exceptions
  • 10.7 Exception aggregation
  • 10.8 Just crash?
  • 10.9 Taking it too far
  • 10.10 Conclusion
  • 11 Design it Twice
  • 12 Why Write Comments? The Four Excuses
  • 12.1 Good code is self-documenting
  • 12.2 I don’t have time to write comments
  • 12.3 Comments get out of date and become misleading
  • 12.4 All the comments I have seen are worthless
  • 12.5 Benefits of well-written comments
  • 12.6 A different opinion: comments are failures
  • 13 Comments Should Describe Things that Aren’t Obvious from the Code
  • 13.1 Pick conventions
  • 13.2 Don’t repeat the code
  • 13.3 Lower-level comments add precision
  • 13.4 Higher-level comments enhance intuition
  • 13.5 Interface documentation
  • 13.6 Implementation comments: what and why, not how
  • 13.7 Cross-module design decisions
  • 13.8 Conclusion
  • 13.9 Answers to questions from Section 13.5
  • 14 Choosing Names
  • 14.1 Example: bad names cause bugs
  • 14.2 Create an image
  • 14.3 Names should be precise
  • 14.4 Use names consistently
  • 14.5 Avoid extra words
  • 14.6 A different opinion: Go style guide
  • 14.7 Conclusion
  • 15 Write The Comments First
  • 15.1 Delayed comments are bad comments
  • 15.2 Write the comments first
  • 15.3 Comments are a design tool
  • 15.4 Early comments are fun comments
  • 15.5 Are early comments expensive?
  • 15.6 Conclusion
  • 16 Modifying Existing Code
  • 16.1 Stay strategic
  • 16.2 Maintaining comments: keep the comments near the code
  • 16.3 Comments belong in the code, not the commit log
  • 16.4 Maintaining comments: avoid duplication
  • 16.5 Maintaining comments: check the diffs
  • 16.6 Higher-level comments are easier to maintain
  • 17 Consistency
  • 17.1 Examples of consistency
  • 17.2 Ensuring consistency
  • 17.3 Taking it too far
  • 17.4 Conclusion
  • 18 Code Should be Obvious
  • 18.1 Things that make code more obvious
  • 18.2 Things that make code less obvious
  • 18.3 Conclusion
  • 19 Software Trends
  • 19.1 Object-oriented programming and inheritance
  • 19.2 Agile development
  • 19.3 Unit tests
  • 19.4 Test-driven development
  • 19.5 Design patterns
  • 19.6 Getters and setters
  • 19.7 Conclusion
  • 20 Designing for Performance
  • 20.1 How to think about performance
  • 20.2 Measure before (and after) modifying
  • 20.3 Design around the critical path
  • 20.4 An example: RAMCloud Buffers
  • 20.5 Conclusion
  • 21 Decide What Matters
  • 21.1 How to decide what matters?
  • 21.2 Minimize what matters
  • 21.3 How to emphasize things that matter
  • 21.4 Mistakes
  • 21.5 Thinking more broadly
  • 22 Conclusion
  • Index
  • Summary of Design Principles
  • Summary of Red Flags