第八章: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.

并不是所有的场景都要下沉复杂度。
第六章中的编辑器的实现,如果下层模块直接提供了backspace能力,看起来下沉了复杂度。但是导致了信息泄露,并没有会让上层代码变得好写。

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.

所有的苦难自己扛 T.T