第八章：Pull complexity downwards
This chapter introduces another way of thinking about how to create deeper classes.
假设正在开发一个新的模块，但是发现有一块不可避免的复杂度，该怎么做： 1. 让模块的使用方来处理复杂度 2. 在模块内部处理掉复杂度 如果复杂度和模块提供的功能关联在一起，那么第二种会更好。大部分模块有比开发人员更多的使用方，所以让开发者承受这一切比使用者更好
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.
it is more important for a module to have a simple interface than a simple implementation.
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 on person.
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.
Example: editor text class
在上章的interface versus implement中举的例子而言 面向行的接口： 实现简单，但是将复杂度都暴露给了调用方，上层模块实现时，需要对行进行分开合并等操作 面向字符的接口： 将实现下沉。使用接口的软件可以插入和删除任意范围的文本，不需要拆分和合并行，变得更加简单。
This approach is better becouse it excapsulates the complexity of spliting and mergeing within the text class ,which reduceds the overall complexity of the system.
Example: configuration parameters
Configuration parameters are an example of moving complexity upwards instead of down.
In some situations it is hard for low-level infrastructore code to know the best policy to apply....so it make s sense for the user to specify a higher priority for those requests. In situations like this, configuration parameters can result in better performance across a broader variety of domains.
Howner, configuration parameters also provide an easy excuse to avoid dealing with important issues and pass them on to someone else. In mayny cases, it's difficult or improssible for users or administrators to determine the right values for the parameters.
Consider a network protocol that must deal with lost packets. If it sends a request but doesn't receive a response within a certain time period, it resends the request. One way to determine the retry interval is to introduce a configuration parameter. However, the transport protocol could compute a reasonable value on its own by measuring the response time for requests that succeed and then using a multiple of this for the retry interval. This approach pulls complexity downward and saves users from having to figure out the right retry interval.
Before exporting a configuration parameter, ask yourself: " will users (or higher-level modules) be able to determine a better value than we can determine here?"
When you do create configuration parameters, see if you can compute reasonable defaults automatically, so users will only need to provide values under exceptional conditions.
Ideally, each module should solve a problem completely; configuration parameters result in an incomplete solution, which adds to system complexity.
Taking it too far
Use discretion when pulling complexity downward; this is an idea that can easily be overdone.
Pulling complexity down makes the most sense:
- the complexity being pulled down is closely related to the class's existing functinality
- pulling the complexity down will result in many simplifications elsewhere in the application
- pulling the complexity down simplifies the class's interface
Remember that the goal is to minimize overall system complexity.
a method that implements the functionality of the backspace key. in chapter 6
It might seem that this is good, since it pulls complexity downward.
adding knowledge of the user interface to the text class doen't simplify higher-level code very much, and the user-interface knowledge doesn't relate to the core functions of the text class. In this case, pulling complexity down just resulted in information leakage.
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.