活用设计模式:如何避免一连串的if else

前段时间知乎上有人发了这么个段子:

某日,老师在课堂上想考考学生们的智商,就问一个男孩: “树上有十只鸟,开枪打死一只,还剩几只?” 
男孩反问:“是无声手枪,还是其他没有声音的枪么?” 
“不是.” 
“枪声有多大?” 
“80~100分贝.” 
“那就是说会震的耳朵疼?” 
“是.” 
“在这个城市里打鸟犯不犯法?” 
‘不犯.” 
“您确定那只鸟真的被打死啦?” 
“确定.”老师已经不耐烦了,”拜托,你告诉我还剩几只就行了,OK?” 
“OK.鸟里有没有聋子?” 
“没有.” 
“有没有鸟智力有问题,呆傻到听到枪响不知道飞的?” 
“没有,智商都在200以上!” 
“有没有关在笼子里的?” 
“没有.” 
“边上还有没有其他的树,树上还有没有其他鸟?” 
“没有.” “方圆十里呢?” “就这么一棵树!” 
“有没有残疾或饿的飞不动的鸟?” 
“没有,都身体倍棒.” 
“算不算怀孕肚子里的小鸟?” 
“都是公的.” 
“都不可能怀孕?” 
“………,决不可能.” 
“打鸟的人眼里有没有花?保证是十只?” 
“没有花,就十只.” 老师脑门上的汗已经流下来了, 
下课铃响起,但男孩仍继续问:“有没有傻的不怕死的?” 
“都怕死.” 
“有没有因为情侣被打中,自己留下来的?” 
“笨蛋,之前不是说都是公的嘛!” 
“**可不可以啊!” 
“………….,性取向都很正常!” 
“会不会一枪打死两只?” 
“不会.” 
“一枪打死三只呢?” 
“不会.” 
“四只呢?” 
“更不会!” 
“五只呢?” 
“绝对不会!!!” 
“那六只总有可能吧?” 
“除非你他妈的是猪生的才有可能!一枪只能打死一只!” 
“…好吧,那么所有的鸟都可以自由活动么?” 
“完全可以.” 
“它们受到惊吓起飞时会不会惊慌失措而互相撞上?” 
“不会,每只鸟都装有卫星导航系统,而且可以自动飞行.” 
“恩,如果您的回答没有骗人,”学生满怀信心的回答,“打死的鸟要是挂在树上没掉下来,那么就剩一只,如果掉下来,就一只不剩.” 
老师推推眼镜,强忍着要昏倒的感觉,颤抖地说道:“你可以去当程序员了……”

有人就在下面问怎么写代码才能避免一连串的if else?

因为他用Python,我就回答:把每一个条件判断都写成一个布尔函数,把这些函数依次放进一个数组/列表。再写一个函数来遍历数组,对每一项,若为假则返回,若为真则继续。

对Java(8之前)来说,没有一等函数,就要把每个条件判断写成Function接口的实现类。

而用Java 8来写,就是:

Collection> conditions = new ArrayList<>();
conditions.add(context -> isGunSilent(context));
conditions.add(context -> isGunSoundBig(context));
conditions.add(context -> isShootingBirdLegal(context));
...

public boolean judge(Context context, Collection> conditions) {
    for (Function cond : conditions) {
        if (!cond.apply(context)) {
            return false;
        }
    }
    return true;
}

Context是个包装类,包含了gun, city, bird, tree等数据。

折腾之后,代码量相比一连串if else略有减少,似乎收益不大?噢,值得注意的是,这种方法具有高度的灵活性!

这些条件可以提前定义好,然后到处复用!你可以任意地组合它们,来构造一段业务逻辑,只需要挑选你要的条件,塞到一个list里面!简直棒!

这是用了哪种设计模式呢,比较像Strategy,我认为还像Template Method: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
我们定义了作为骨架的judge():for循环,遇到false中止。然后在把步骤在子类中实现(虽然与judge()不属于同一个父类)。
虽然结构跟书上不一样,但是有相同的精神。

Chain of Responsibility需要前后链接,节点对其后的子链有控制力,所以不那么像。

你可能感兴趣的:(java,设计模式)