1.5.4 抽象层一致性原则

《程序员的底层思维》学习笔记目录

原书:《程序员的底层思维》 | 作者:张建飞

抽象层次要保持一致

一致性可以

  • 减少混乱
  • 降低理解成本

抽象层次一致性原则(Single Level of Abstration Principle,SLAP)是 ThoughtWorks 的总监级咨询师 Neal Ford 在《卓有成效的程序员》一书中提出来的概念, 其思想源自 Kent Beck 提出的组合方法模式(Composed Method Pattern,CMP)

SLAP 强调每个方法中的所有代码都处于同一级抽象层次。如果高层次抽象和底层细节杂糅在一起,就会显得代码凌乱,难以理解,从而造成复杂性。

假如有一个冲泡咖啡的需求,其制作过程分为 3 步:

  1. 倒入咖啡粉
  2. 加入开水
  3. 搅拌

伪代码

1
2
3
4
5
void mackCoffee(){
    倒入咖啡粉();
    加入开水();
    搅拌();
}

新需求

  • 选择不同的咖啡粉
  • 选择不同的风味

有点糟糕的代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
void mackCoffee(CoffeePowder 咖啡粉类型, boolean 加奶, boolean 加糖){
    if(咖啡粉类型 == 粗研磨){
        倒入粗研磨咖啡粉();
    }else if(咖啡粉类型 == 中研磨){
        倒入中研磨咖啡粉();
    }else if(咖啡粉类型 == 细研磨){
        倒入细研磨咖啡粉();
    }
    
    加入开水();

    // 选择口味
    if(加奶){
        加奶();
    }
    if(加糖){
        加糖();
    }

    搅拌();
}

如果再加新的需求,代码会变的越来越可怕

问题分析

诱因: 增加新需求

导致混乱的原因: 不再满足 SLAP

  • 选择用什么咖啡粉是“倒入咖啡粉”这个步骤应该考虑的实现细节,和主流程步骤一个抽象层次上
  • 同理,加糖、加奶也是实现细节

优化

  1. 倒入咖啡粉(从多种咖啡粉中选择一种)
  2. 加入开水
  3. 选择风味(加糖、加奶任意组合)
  4. 搅拌

根据 SLAP 重构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void mackCoffee(CoffeePowder 咖啡粉类型, boolean 加奶, boolean 加糖){
    选择咖啡粉(咖啡粉类型);
    加入开水();
    选择口味(加奶, 加糖);
    搅拌();
}

void 选择咖啡粉(CoffeePowder 咖啡粉类型){
    if(咖啡粉类型 == 粗研磨){
        倒入粗研磨咖啡粉();
    }else if(咖啡粉类型 == 中研磨){
        倒入中研磨咖啡粉();
    }else if(咖啡粉类型 == 细研磨){
        倒入细研磨咖啡粉();
    }
}

void 选择口味(boolean 加奶, boolean 加糖){
    if(加奶){
        加奶();
    }
    if(加糖){
        加糖();
    }
}

总结

这种代码重构是结构化思维的一种体现

结构化思维的要点:结构的每一层要属于同一个逻辑范畴、同一个抽象层次。

comments powered by Disqus