写代码不用"if"行不行,曾经的反 "if" 运动

如果在IT行业的时间够长的话,可能还记得大约10几年前,设计模式风靡一时的时候,有过一段反 "if" 的运动。

所谓的反"if"运动,其实是夸大了"if"语句带来的问题,比如当时提出的问题有:

  1. 代码不好维护,特别是if或者else中的代码比较多的时候
  2. ifelse if分支太多的时候,代码难以阅读和修改
  3. 阅读含有if的代码时,必须在自己的头脑中模拟执行,会消耗你的精神能量
  4. ... ... 等等

这些问题确实存在,但是因为这些就彻底禁止if的话,就过于极端,因噎废食了。

代码中分支和循环是不可避免的,完全禁止if之后,在某些时候会产生了更加复杂和令人发指的代码,

所以,最后这个反"if"的运动也不了了之,慢慢消亡了。

不过,为了反"if"而产生的一些替代方案,我挑了三个 还值得一看的方案,供大家参考参考。

其它还有很多方案都不太靠谱,就不一一赘述了。

1. 拆分成多个方法

这种重构"if"的方法是将每个分支单独封装成一个独立的方法。

比如:

python 复制代码
def select_model(is_regression=True):
    if is_regression:
        print("选择【回归】模型")
    else:
        print("选择【分类】模型")

# 测试代码
select_model(True)
select_model(False)

# 运行结果
选择【回归】模型
选择【分类】模型

示例中,方法select_model通过is_regression参数来决定调用哪种模型。

重构之后:

python 复制代码
def select_regression():
        print("选择【回归】模型")

def select_classifier():
        print("选择【分类】模型")

# 测试代码
select_regression()
select_classifier()

# 运行结果
选择【回归】模型
选择【分类】模型

将原方法拆分为两个新方法,"if"就消失了。

2. 改成多态

如果一个函数中分支比较多,比如:

python 复制代码
def cry(animal):
    if animal == "dog":
        print("{} :汪汪~".format(animal))
    elif animal == "cat":
        print("{} :喵喵~".format(animal))
    elif animal == "sheep":
        print("{} :咩咩~".format(animal))
    elif animal == "cow":
        print("{} :哞哞~".format(animal))
    else:
        print("无法识别动物:{}".format(animal))

# 测试代码
cry("dog")
cry("cat")
cry("sheep")
cry("cow")

# 运行结果
dog :汪汪~
cat :喵喵~
sheep :咩咩~
cow :哞哞~

cry函数根据不同的参数来判断输出内容,

如果分支多了,并且每个分支中的代码也比较多的时候,会比较难于维护。

对于上面的"if"分支较多的情况,可以用多态的方式来改造。

也就是,封装一个抽象类,其中包含抽象方法cry,然后不同的动物继承抽象类实现自己的cry方法。

python 复制代码
from abc import ABCMeta, abstractclassmethod

class Animal(metaclass=ABCMeta):
    def __init__(self, name) -> None:
        self.name = name

    @abstractclassmethod
    def cry(self):
        pass

class Dog(Animal):
    def __init__(self) -> None:
        super().__init__("dog")

    def cry(self):
        print("{} :汪汪~".format(self.name))


class Cat(Animal):
    def __init__(self) -> None:
        super().__init__("cat")

    def cry(self):
        print("{} :喵喵~".format(self.name))


class Sheep(Animal):
    def __init__(self) -> None:
        super().__init__("sheep")

    def cry(self):
        print("{} :咩咩~".format(self.name))


class Cow(Animal):
    def __init__(self) -> None:
        super().__init__("cow")

    def cry(self):
        print("{} :哞哞~".format(self.name))

# 测试代码
animal = Dog()
animal.cry()

animal = Cat()
animal.cry()

animal = Sheep()
animal.cry()

animal = Cow()
animal.cry()

# 运行结果
dog :汪汪~
cat :喵喵~
sheep :咩咩~
cow :哞哞~

3. 将条件判断内联

对于比较复杂的条件判断,可以用内联的方式的来改善。

比如,下面构造一个略微复杂的判断:

python 复制代码
def complex_judge(foo, bar, baz):
    if foo:
        if bar:
            return True

    if baz:
        return True
    else:
        return False

# 测试代码
print(complex_judge(True, True, False))
print(complex_judge(True, False, False))
print(complex_judge(False, True, True))

# 运行结果
True
False
True

这样写不仅阅读比较困难,增加或修改判断条件时也很麻烦。

用内联的方式(也就是用 andor)修改后,简洁很多。

python 复制代码
def complex_judge(foo, bar, baz):
    return foo and bar or baz

# 测试代码
print(complex_judge(True, True, False))
print(complex_judge(True, False, False))
print(complex_judge(False, True, True))

# 运行结果
True
False
True

4. 总结

"if"运动早已结束,对"if"彻底抛弃显得很荒谬,但也不能对此全盘否定。
"if"语句会影响阅读代码时流畅的思路,对代码中"if"的使用保持慎重的态度还是很有必要的。

相关推荐
databook2 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar3 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780514 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_4 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
晨米酱5 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机10 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机11 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机11 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机11 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i12 小时前
drf初步梳理
python·django