如果在IT行业的时间够长的话,可能还记得大约10几年前,设计模式风靡一时的时候,有过一段反 "if"
的运动。
所谓的反"if"
运动,其实是夸大了"if"
语句带来的问题,比如当时提出的问题有:
- 代码不好维护,特别是
if
或者else
中的代码比较多的时候 if
和else if
分支太多的时候,代码难以阅读和修改- 阅读含有
if
的代码时,必须在自己的头脑中模拟执行,会消耗你的精神能量 - … … 等等
这些问题确实存在,但是因为这些就彻底禁止if
的话,就过于极端,因噎废食了。
代码中分支和循环是不可避免的,完全禁止if
之后,在某些时候会产生了更加复杂和令人发指的代码,
所以,最后这个反"if"
的运动也不了了之,慢慢消亡了。
不过,为了反"if"
而产生的一些替代方案,我挑了三个还值得一看的方案,供大家参考参考。
其它还有很多方案都不太靠谱,就不一一赘述了。
1. 拆分成多个方法
这种重构"if"
的方法是将每个分支单独封装成一个独立的方法。
比如:
def select_model(is_regression=True):
if is_regression:
print("选择【回归】模型")
else:
print("选择【分类】模型")
# 测试代码
select_model(True)
select_model(False)
# 运行结果
选择【回归】模型
选择【分类】模型
示例中,方法select_model
通过is_regression
参数来决定调用哪种模型。
重构之后:
def select_regression():
print("选择【回归】模型")
def select_classifier():
print("选择【分类】模型")
# 测试代码
select_regression()
select_classifier()
# 运行结果
选择【回归】模型
选择【分类】模型
将原方法拆分为两个新方法,"if"
就消失了。
2. 改成多态
如果一个函数中分支比较多,比如:
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
方法。
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. 将条件判断内联
对于比较复杂的条件判断,可以用内联的方式的来改善。
比如,下面构造一个略微复杂的判断:
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
这样写不仅阅读比较困难,增加或修改判断条件时也很麻烦。
用内联的方式(也就是用 and
和 or
)修改后,简洁很多。
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"
的使用保持慎重的态度还是很有必要的。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容