A Philosophy of Software Design, 2nd Edition
  • 简体中文
  • English
  • 繁体中文
GitHub
  • 简体中文
  • English
  • 繁体中文
GitHub
  • Introduction
  • Preface
  • Chapter 1 Introduction
  • Chapter 2 The Nature of Complexity
  • Chapter 3 Working Code Isn’t Enough(Strategic vs. Tactical Programming)
  • Chapter 4 Modules Should Be Deep
  • Chapter 5 Information Hiding (and Leakage)
  • Chapter 6 General-Purpose Modules are Deeper
  • Chapter 7 Different Layer, Different Abstraction
  • Chapter 8 Pull Complexity Downwards
  • Chapter 9 Better Together Or Better Apart?
  • Chapter 10 Define Errors Out Of Existence
  • Chapter 11 Design it Twice
  • Chapter 12 Why Write Comments? The Four Excuses
  • Chapter 13 Comments Should Describe Things that Aren’t Obvious from the Code
  • Chapter 14 Choosing Names
  • Chapter 15 Write The Comments First
  • Chapter 16 Modifying Existing Code
  • Chapter 17 Consistency
  • Chapter 18 Code Should be Obvious
  • Chapter 19 Software Trends
  • Chapter 20 Designing for Performance
  • Chapter 21 Decide What Matters
  • Chapter 22 Conclusion
  • Summary

Chapter 8 Pull Complexity Downwards

This chapter introduces another way of thinking about how to create deeper classes. Suppose that you are developing a new module, and you discover a piece of unavoidable complexity. Which is better: should you let users of the module deal with the complexity, or should you handle the complexity internally within the module? If the complexity is related to the functionality provided by the module, then the second answer is usually the right one. Most modules have more users than developers, so it is better for the developers to suffer than the users. As a module developer, you should strive to make life as easy as possible for the users of your module, even if that means extra work for you. Another way of expressing this idea is that it is more important for a module to have a simple interface than a simple implementation.

As a developer, it’s tempting to behave in the opposite fashion: solve the easy problems and punt the hard ones to someone else. If a condition arises that you’re not certain how to deal with, the easiest thing is to throw an exception and let the caller handle it. If you are not certain what policy to implement, you can define a few configuration parameters to control the policy and leave it up to the system administrator to figure out the best values for them.

Approaches like these will make your life easier in the short term, but they amplify complexity, so that many people must deal with a problem, rather than just one person. For example, if a class throws an exception, every caller of the class will have to deal with it. If a class exports configuration parameters, every system administrator in every installation will have to learn how to set them.

8.1 Example: editor text class

8.2 Example: configuration parameters

8.3 Taking it too far

8.4 Conclusion

When developing a module, look for opportunities to take a little bit of extra suffering upon yourself in order to reduce the suffering of your users.

Last Updated: 5/14/25, 1:24 AM
Prev
Chapter 7 Different Layer, Different Abstraction
Next
Chapter 9 Better Together Or Better Apart?