写代码不用"if"行不行,曾经的反 if 运动
如果在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"的使用保持慎重的態度還是很有必要的。
總結
以上是生活随笔為你收集整理的写代码不用"if"行不行,曾经的反 if 运动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flask 使用Jinja2模板引擎
- 下一篇: java读取照片Exif信息到实体类