Guard Clauses - zbavení se if-else
Dlouho jsem přemýšlel a zkoušel různé techniky na to, jak být lepší v psaní kódu. Jedna z mnoha technik/postupů je tzv. Guard-clauses technika. Je to velmi jednoduchý přístup ke strukturování funkcí/metod. Pokusím se tuto techniku v krátkosti představit.
Guard-clauses technika nám umožní psát daleko čitelnější a udržitelnější kód.
Tzv. guard by měl být takový boolean výraz, který se vyhodnotí jako False, pokud má v dané funkci/metodě pokračovat. Jinak funkce/metoda skončí.
Pokud je kód správně napsaný s tímto design-patternem, člověk, který na kód kouká poprvé by měl hned vědět, co se stane když...
Proč bychom takové guardy potřebovali?
- kód nebude tak moc vnořený do sebe -> nebudeme se ztrácet v odsazování
- odstranění else větví nám způsobí daleko lepší čitelnost kódu
- výrazy se stanou hrozně jednoduchými a máme kontrolu nad tím, co se stane, když kód selže
Jak to v praxi funguje?
Pokud mám kód, který vypadá např. takto:
def not_guarded_function(request):
if request.user:
if request.user.is_authenticated:
data = request.data
if data.get('success', False):
return data
else:
raise Exception('Data not valid')
else:
raise Exception('User not authenticated')
else:
raise Exception('User not found')
Tak si hned můžu všimnout, že se v kódu skoro nedá orientovat. S trochou luštění dokážu zjistit, jaká exceptiona se vykoná po nějakém ifu.
Python nám to trochu usnadňuje odsazováním, ale i tak, orientace je velmi špatná. Nehledě na to, že pokud mám splnit PEP8, tak se za chvilku nevejdu do maximálního počtu znaků na řádek.
Pokud použiji guard-clause pattern, kód se najednou promění v naprosto přehledný a čitelný kód:
def guarded_function(request):
if not request.user:
raise Exception('User not found')
if not request.user.is_authenticated:
raise Exception('User not authenticated')
data = request.data
if not data.get('success', False):
raise Exception('Data not valid')
return data
Můžu si hned všimnout, co se stane když... Zmizely nám všechny else bloky - nejsou potřeba!
Kód je přehledný a v hlavní části funkce - neodsazené - je kód, na který se mám soustředit.
Ve výsledku Guard-clauses pattern jenom invertoval podmínky. Stačí velmi málo a váš kód se promění v kód, za který by se nemusel stydět ani nějaký seniornější vývojář.