Kodunuz Sette Formda ve Kimse Kabul Etmek İstemiyor
Bazen bir metodu açtığınızda sağ tarafta ne göreceğinizi biliyor musunuz? Girinti sürekli artmaya başlıyor, kod bir ok şekli alıyor ve en derinde, derinlerde gerçekten önemli olan satır yer alıyor.
Bu duruma arrow code (ok kodu) diyoruz. Daha dramatik olanı ise “kayıp piramidi”.
Bu durumla genelde baştan itibaren çok sıkı bir sorun yoktur. Bir if ile başlayarak, oraya bir validasyon ekle, bir durum daha ekle, bir istisna ile uğraş… Ve ne zaman fark edersiniz ki, altı satırlık kapama parantezini (}) çözmek için gözlerinizi yormanız gerekiyor, hangi if‘in hangi } ile kapandığını bulmak için.
Pratikteki Problem
Bir siparişi işlemek için bir metot düşünelim. Masum görünüyor, ama girintilere dikkat et:
public function processar(Order $order)
{
if ($order->isPago()) {
if ($order->itens->isNotEmpty()) {
if ($order->cliente->estaAtivo()) {
if (! $order->foiEnviado()) {
// nihayet, gerçekten önemli olan kod
$this->enviar($order);
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
return false;
}
Önemli satıra ulaşmak için ($this->enviar($order)) dört if geçmeniz gerekecek ve hangi else‘in hangi bloğu kapattığını karıştırmamaya çalıştığınız bir durumdasınız. Ya yarın daha fazla kural gelirse? Daha içe bir katman daha eklemenize neden olur. Ok büyür.
Bu kod zorlu değil çünkü sorun zor; zor çünkü geriye doğru yazılmış.
Kavram: Hataları Önce Kontrol Et
Early return (veya “koruma şartı”, guard clause) fikri, çıkış durumlarını metodun başında ele alıp hemen çıkmanızı sağlamaktır. “Mutlu yolu” derinlemesine gömmek yerine, mantığı ters çeviriyorsunuz:
“Ödenmediyse çık! Ürün yoksa çık! Müşteri aktif değilse çık! Her şey tamamsa, o zaman çalıştır.”
Mutlu yol, metodun ana seviyesine yerleştirilmiştir, hiç girinti yoktur. İstisnalar yukarıda, her biri çözüme kavuşturulmuş ve unutulmuştur. Yukarıdan aşağıya okuyarak birer birer bir koşul geçer, zihninizde bir şey tutmanıza gerek kalmadan okuyabilirsiniz.
Çözüm: Aynı Metot, Artık Anlaşılır
public function processar(Order $order): bool
{
if (! $order->isPago()) {
return false;
}
if ($order->itens->isEmpty()) {
return false;
}
if (! $order->cliente->estaAtivo()) {
return false;
}
if ($order->foiEnviado()) {
return false;
}
// mutlu yol, ana seviyede, hiç ok yok
$this->enviar($order);
return true;
}
Hiç else yok. Hiç gömme yok. Her bir if basit bir soru soruyor: “Burada durmak için bir sebep var mı?”. Varsa dur! Eğer sona geldiyseniz bu, tüm filtrelerden geçtiğiniz ve artık gerçekten iş yapabileceğiniz anlamına gelir.
Ve ek olarak: yarın yeni bir kural eklemek, araya bir koruma bloku yerleştirmek demek. Yapıyı değiştirmek zorunda kalmazsınız, içe doğru itmek zorunda kalmazsınız.
Pratikte Kullanma Yöntemleri
İstisna fırlatarak dönüş yerine — aynı mantıkla, Services ve Actions’da harika çalışır:
public function reembolsar(Order $order): void
{
if (! $order->isPago()) {
throw new OrderException('Ödenmemiş bir siparişi geri ödeyemezsiniz.');
}
if ($order->foiReembolsado()) {
throw new OrderException('Bu sipariş daha önce geri ödendi.');
}
$this->gateway->refund($order);
}
Bir döngü içinde erken çıkış ile continue ile — aynı felsefe, ana gövdeyi çevreleyen dev bir if‘den kaçınır:
foreach ($usuarios as $usuario) {
if ($usuario->optOut) {
continue; // bunu atlarsınız ve devam edersiniz
}
$this->notificar($usuario);
}
Blade’de de, @continue ve @break ile, tüm görünümü bir @if içinde gömme.
Uygun Kullanım: Her Yerde Dönüş Yok
Burada, bu konuyu okuyan herkesin başından geçen bir durum var; yani return kullanarak modern görünmeye çalışmak.
Early return, gerçekten var olan güçlü çıkış şartlarıyla parlıyor: validasyonlar, ön koşullar, ana akışı engelleyen kenar durumları. Bu durumlar karmaşıklığı azaltır.
Ama değil: mantık akışında her biri farklı bir noktadan çıkan on tane return bulmak, kimin hangi noktada sonlandığını anlamak için. Bu, early return değil, bu bir kaçış.
Mesela: Koruma şartları yukarıda gruplanır ve hatayı çözüyor. Mutlu yol, son noktada tek başına kalır. Eğer return ifadeleriniz kodun ortasına dağılmışsa, bir sorunu diğerine çevirdiniz demektir.
Bonus: Şimdi Ne Olacak?
Projenizde en karmaşık metodu açın — bunu hangi metodun en karmaşık olduğunu biliyorsunuz. Kaç tane girinti katmanı olduğunu sayın. İki veya üçten fazlaysa, büyük ihtimalle baştaki if‘leri koruma başlıkları olarak tersten çevirip düzleştirebilirsiniz.
Bir ipucu: tüm else ifadelerini önce değerlendirin. Sadece geri dönmek için orada olan her else, güçlü bir adaydır ve early return haline gelebilir, kaybolabilir.
Sayfayı Kapatmadan Önce
Okunabilirlik, güzel kod sevenler için bir şey değildir. Gelecekteki kendinizi (ya da bakımını yapacak talihsiz kişiyi) bilgilendirmek için zamandan tasarruf sağlamaktır.
Siz hangi taraftasınız: “Önce hataları işleyip çıkın” mı, yoksa “iç içe if’lere sevgi mi” besliyorsunuz? Yorumlarda paylaşın — ve iç içe geçmiş bir else seven birini tanıyorsanız, işaretleyin. 😅
Kaynak: Orijinal Makale


