Extending New Operations or Variants.
当我们尝试扩展以上矩阵,即增添新的 operations 或 variants 时,functional programming 的 by-column 方法与 OOP 的 by-row 方法之间的区别将更加明显。
首先考虑 functional programming。
- Adding a new operation is easy. We can implement a new function without editing any existing code. 由于 FP 是按列,也就是按函数实现程序的,新增一个 operation 等价于在矩阵中新增一列。
- Adding a new data variant is less pleasent. We need to go back and change all our functions to add a new case. 新增一个 variant 等价于在矩阵中新增一行;但 FP 是按列实现程序的,因此在每一列后我们都需要新增一个单元 (case)。
Object-oriented programming 则与其完全相反。
- Adding a new variant is easy: implement a new subclass without editing any existing code.
- Adding a new operation is less pleasant. We need to go back and change all classes to add a new method.
Functional decomposition allows new operations and object-oriented decomposition allows new variants without modifying existing code and without explicitly planning for it.
但在设计程序时,如果做好提前的计划,或者使用某些 somewhat awkward programming techniques,那么在 FP 中添加 variants 与在 OOP 中添加 operations 也能较为简单的实现。
代码的设计与结构允许方便的进行删减或添加新功能,而不会引起大规模的重构或破坏原有的功能,这种性质称为代码的 extensibility (可扩展性)。
若我们只需要添加新的 operations,那么一个 FP-style 的程序显然要比 OOP-style 的程序可扩展性更强;反之,一个只需要添加新的 variants 的应用背景下 OOP-style 要比 FP-style 的程序可扩展性更强。
问题在于 (1) the future is often difficult to predict; we may not know what extensions are likely, and (2) both forms of extension may be likely.
实际上,软件的设计 rubostness (鲁棒性) 与 extensibility (可扩展性) 鱼与熊掌难以兼得。由于要为未来做规划,可扩展性高的程序往往 need more work to develop, harder reason about locally and harder to change without breaking extensions.