布林值判断的一些豆技巧(弄不好也是会造成专案死掉的)

前天讲了豆技巧,今天再讲一点好了...

假设有个情境是要用数个布林值来判断接下来要做什麽动作,先从简单的两个布林值(a, b)开始。

我们会得到四种组合...或说四个「程序码的分支」。


if(a == true && b == true){...}
else if(a != true && b == true){...}
else if(a == true && b != true){...}
else{...}

同样的豆技巧一样可以用在简化这个情境上...

这个技巧的原理基本上是以二进位计算为基础,其实一个八位元数字等於八个布林值所组成,以此类推一个十六位元数字等於十六个布林值所组成,一个三十二位元数字等於三十二个布林值所组成。

但先简单一点,说说看怎麽用在两个布林值的简化上。

0等於「所有布林值皆为false」,那1就等於「第一个布林值为true」。

换个比较好懂的写法...把0跟1转化成八位元二进位表达。

00000000等於「所有布林值皆为false」,那00000001就等於「第一个布林值为true」。

再来...

那00000010(2)就等於「第二个布林值为true」。
那00000011(1+2)就等於「第一与第二个布林值皆为true」。

把这个概念应用在判断上,就不需要写判断式,改成如下...

首先定义一个接口来实作每个组合要对应的动作。

interface Act{
  void act();
}

然後...

Act[] acts = new Act[4]; //因为有两个布林值有四种情况

int index = 0;
index += (a)?1:0;
index += (a)?2:0;

acts[index].act();

以此类推,一个index最多可以对应32组布林值判断。

但其实这种豆技巧反映的是「位元运算」的应用。「位元运算」可以应用的地方还很多,而且不是所有人都喜欢用Strategy模式来解决问题。

更重要的是...会害专案死掉的「布林值判断」并不在「写太多」,而在於「写太杂」。

像下面这种情况一旦发生,後续维护升级扩充就很难成功:

if(a){
  funcA();
  funcB();
  funcD();
}
else{
  funcC();
  funcB();
  funcA();
}

funcA/funB/funC/funcD只是为了方便表达,但如果是尚未集合成函数的散乱程序码,只是功能相同而已。

这种写法还可能会有魔改变化形式,如果我们多增加了b和c的布林值...

if(a){
  funcA();
  if(b)
    funcB();
  funcD();
}
else{
  funcC();
  if(b)
    funcB();
  funcA();
}

维护这种程序码最大的阻碍,首先在於「程序码又多又长」,所以後续维护的人经常无法看出结构上可以简单归类,所以就不知道funcA同时存在於两个地方,结果修改了其中一处,但另一处却没修改到,结果徒增测试所需要耗费的资源。

(这是根本上「不重构」「不优化」造成的结果。但现阶段不想讨论这个。)

优化、避免这种写法出现的技巧,其实是类似的。主要就是避免因为使用「if...else」造成「程序码出现分支」。

先不要使用「Act」这样的介面,就单纯地看一下没有分支的程序码长什麽样...

if(a){  funcA();}
else{  funcC();}

if(b){  funcB();}

if(a){  funcD();}
else{  funcA();}

虽然还是使用了「if...else」,但程序码被很清楚的区隔开,後续会比较好阅读,发现funcA段的程序码重复、可以独立成一个函数的机会也能高很多。

(虽然这种写法的好处很明显,但我也看过有些工程师坚持「这种写法不直觉」而否定这种写法。)

比起测试一个工程师是否懂「MVVM在官方网页的定义」「某某元件在官方API的解释」,「能理解」或「能使用」这种豆技巧是否更能反映一个工程师的能力?(先不提程序套件的知识,至少在建构程序思维的灵活度上,这些问题更有指标性才对。)


<<:  [Day 14] Leetcode 115. Distinct Subsequences (C++)

>>:  [Day04] 第四章- 初探金流API文件-3 (sign透过nodejs实作)

Day29 javascript RegExp介绍

今天要来看的是JavaScript RegExp 对象,因为刚好最近做表单要用到,因此就来顺便做点笔...

Day 6 追加训练

根据昨天的测试我们知道小画家画风的数字模型认不出来,那麽我们可以追加训练让它学习自己画的字。 这次我...

第一次进入赌场是否要搞懂一下规则 - 永丰金 Shioaji API 初探

事前提要: 本 API 系为 永丰金 PYTHON API,尚未申请的朋友们,有两个方法可以申请 洽...

28. 团队成功的要素是什麽?

前言 这个演讲蛮general的,也适合任何leader来看看。如果你觉得team里面的人都不太爱...

Day 18 - Spring Boot 日志纪录

日志纪录是网站的一个非常重要的功能,不论是对外的使用者或是对内的管理,实际运营上一定都会遇到许许多多...