Doğrusal kod daha okunaklıdır
(blog.separateconcerns.com)- Soyutlama seviyesini ayırmak için kodu küçük fonksiyonlara bölmek yerine, yukarıdan aşağıya akan doğrusal kodun genel akışı takip etmeyi daha kolaylaştırdığı savunuluyor
- Fonksiyon çıkarımıyla yukarıdan aşağıya (top-down) bir yapı kurulduğunda,
bakevebakePizzagibi adları benzer fonksiyonlar arasında gidip gelerek kontrol etmek gerekebiliyor - Fırının önceden ısıtılmasının nerede yapıldığı ya da pizzayı iki kez çevirdiğinizde ne olacağı gibi konularda, küçük fonksiyonlar niyeti göstermesine rağmen gerçek davranışı gizleyebilir
- Doğrusal koda adım adım yorumlar eklendiğinde, dolaylı başvuruları artırmadan işin niyetini açıklayabildiği için ek soyutlamadan daha okunaklı olabilir
- Yalnızca bir kez kullanılan küçük fonksiyonları çıkarmak doğrusallık kaybına yol açar; örnekteki fırın oluşturma biçiminde olduğu gibi, gerçek kodda performans sorunlarını bile ortaya çıkarabilir
Fonksiyon çıkarmaktan daha önemli olan durumlar: doğrusallık
- Google Testing Blog örneği, iki farklı
createPizzauygulamasını karşılaştırıyor ve sağdaki uygulamanın soyutlama seviyelerini karıştırmadığı için daha okunaklı ve yukarıdan aşağıya (top-down) olduğu görüşünü savunuyor - Karşı görüşe göre ise soldaki uygulamada daha önemli olan şey, ekran üzerinde yukarıdan aşağıya doğrusal olarak okunabilen kod olması
- Sağdaki uygulamada tüm davranışı anlamak için birden fazla küçük fonksiyon tanımına gitmek gerekiyor
- Sunum biçimi nedeniyle sağdaki kodun bir kısmı gizlendiğinden, iki uygulama benzer boyutta görünüyor; oysa gerçekte sağdaki daha uzun
- Fonksiyon çıkarmak, yalnızca isimlere bakarak davranışı yeterince anlamayı zorlaştırabilir
- Hem
bakehem debakePizzaolduğunda, hangisinin fırını ısıttığını hemen anlamak zor - Aynı pizzayı iki kez çevirdiğinizde işlemin idempotent olup olmadığını ya da sonucu bozup bozmadığını anlamak için iç uygulamaya bakmak gerekir
- Hem
Yorum eklenmiş doğrusal kod ve fırın örneği
- Soldaki doğrusal koda sağdaki fonksiyon adlarının yorum olarak eklendiği sürüm, en okunaklı biçim olarak değerlendiriliyor
Prepare pizza,Add toppings,Heat oven,Bake pizza,Box and slicegibi yorumlar her adımın niyetini ortaya koyuyor- Okunabilirlik, ek soyutlama katmanları ve dolaylı başvurulardan değil, o anda yapılan işi doğru şekilde anlatmaktan geliyor
- Sonuç, yalnızca bir kez kullanılan küçük fonksiyonların doğrusal koddan çıkarılmaması gerektiği yönüne daha yakın
- Küçük fonksiyon çıkarmanın faydasının doğrusallık kaybını telafi etmediği düşünülüyor
- Örnekteki fırın işleyişi de yapısal olarak tuhaf bulunuyor
- Fırının önceden ısıtılması kendi başına tamamlanmış bir davranış olduğundan, bunun fırının bir metodu olması daha uygun
- Tek bir pizza yapılırken her seferinde yeni bir fırın oluşturulup önceden ısıtılması, gerçekçi kullanım biçimiyle uyuşmuyor
- Gerçek kodda da bu tür yapılar görülebiliyor ve bazen performans sorunlarına yol açabiliyor
- Fırın,
createPizzaiçinde yeni oluşturulmak yerine büyük olasılıkla parametre olarak alınmalı- Fırını sağlamak, çağıranın sorumluluğuna daha yakın
- Akış pizzayı kutuya koymaksa, pizza yerine kutuyu döndüren bir arayüz daha doğal olabilir
1 yorum
Hacker News yorumları
Bu bir stil meselesi; yemek yapmak gibi, tuzun fazlası da azı da yemeği mahveder.
Umarım burada kimse 1000 satırlık bir tanrı fonksiyonu önermiyordur; fonksiyon başına en fazla 5 satır da okunaklı değildir. Nereden bölüneceği muhakeme, iyi bir sezgi ve yineleme gerektirir. İlk denenen soyutlama pek iyi olmadı diye soyutlamadan vazgeçmek gerekmez; birkaç kez refactor edince iş alanına iyi uyan sınıflar ve API’ler ortaya çıkabilir.
Aynı zamanda soyutlama konusunda fazla aceleci olmamak ya da birkaç satır tekrar yüzünden ölümcül yara almış gibi davranmamak gerekir. Erken soyutlama, birlikte evrilmesi gerekmeyen kodları kolayca birbirine bağlar. Yalnızca tek bir yerden çağrılan bir fonksiyonu çıkarıp bir iş birimini gizlemek algoritmayı temizleştirebilir; özellikle boilerplate’i ya da iş mantığıyla DB bağlantısı yönetimi gibi altyapı kaygılarının karışımını gizlerken yararlıdır. Ancak dikkatli kullanılmalı; aynı soyutlama düzeyinde olması gereken adımları parçalamaktan kaçınmak iyi olur.
Birlikte çalıştığım biri, “okunması kolay” olduğu gerekçesiyle tüm boolean koşulları fonksiyona çıkarır, “yorumlar kötüdür” gerekçesiyle hiç yorum yazmazdı. O kitabı sevmiyorum; çünkü bu tür kötü tavsiyeleri körü körüne izleyen fanatikler üretiyor.
Bazen alanın kendisi 1000 satırlık bir tanrı fonksiyonu gerektirebilir; mantık ve işler tek yerde toplandığı için 20 adet 50 satırlık fonksiyondan çok daha okunaklı olabilir. Sonuçta bütünü anlamak için o 20 fonksiyonun hepsini okumak gerekir; ayrıca biri bunların bazılarını yeniden kullanmaya kalkıp onları asıl işte olmayan 2-3 gereksinime uyacak şekilde ayarlayabilir ve belirli bir mantığı alakasız kullanım senaryolarına bağlayabilir.
Eğer o fonksiyon saf bir fonksiyonsa, 1000 satır da olsa 10000 satır da olsa fark etmez; hâlâ makul olduğunu düşünüyorum.
Yemek tarifleri de zaten oldukça soyutlanmıştır. “Soğanı hafifçe sotele” dendiğinde, soğanı nasıl doğrayacağını ve hafifçe sotelemenin algoritmasını zaten bildiğin varsayılır. Her şeyi inline yazarsan okunamaz hale gelir.
Kod da benzer. Soyutlamayı katı biçimde dışlarsan, dilin izin verdiği en düşük düzeye inersin; bu kesinlikle okunması kolay kod değildir. Örneğin Python’ın
decodemetodu yerine Unicode çözmeyi elle yapmaya kalkarsan, programın gerçekte ne yaptığını anlamak çok zorlaşır. Dil basit ve iyi doğrulanmış bir soyutlama sunduğu için kimse bunu yapmaz; peki kendi basit ve iyi doğrulanmış soyutlamanı oluşturup bunu iş mantığının genelinde kullanmaktan farkı nedir?Zor olan, kimsenin tekrar dokunmasına gerek kalmayacak kadar iyi seçilmiş bir soyutlama oluşturmaktır.
Şu an kod satırları benzer görünüyor diye gelecekte de aynı olmaları ya da aynı tutulmaları gerekmez. “Kod neredeyse tekrar ediyor” diye iki farklı kullanım senaryosunu zorla birleştirirseniz, zamanla hiçbir şeyi soyutlayamayan bir soyutlamaya dönüşmesi kolaydır.
Kullanım senaryoları fazla ayrışırsa, uygulama ya mantığın büyük kısmını çağıran tarafa iter ya da farkları flag’lerle dışa açıp içeride iki farklı uygulamayı yan yana tutar. İlki sığ bir soyutlamadır ve değeri düşüktür; ikincisi ise iki bağımsız uygulamadan daha az nettir.
Örnek kod fazla basit olduğu için doğrusal kodun daha okunur olması elbette doğal, ama bu fikir iyi ölçeklenmiyor
Yeniden kullanılabilirlik ya da birim test edilebilirliği de düşünülmeli; tüm kodu tek bir fonksiyona koyarsanız, okunan kod bloğuyla ilgili de olabilecek ilgisiz de olabilecek tüm yerel değişkenler kapsam içinde olur ve akıl yürütmek zorlaşabilir
Yine de deneyimsiz olduğum dönemlere dönüp bakınca, gayet düzgün doğrusal kodu fazla modülerleştirip oradan oraya zıplamayı gerektiren, bakımı daha zor koda dönüştürdüğüm çok oldu. İlk yazılan hâlin, o an kafamdaki düşünce akışına daha yakın olması ve okurun da muhtemelen onu o şekilde yorumlama olasılığının yüksek olması gibi bir avantajı var. Aşırı refactoring bunu ortadan kaldırabilir
Sonuçta programlama zanaate daha yakın; duruma uygun seçimi yapmada deneyim yardımcı olur
Amacı tek bir şeydi. Uygulamanın bir köşesinde, bir platformda kullanılan tekil HTML sayfalarını, başka bir platformun native hissini taklit eden bir carousel'e dönüştürme işiydi ve o platform ile uygulamanın o alanına son derece özeldi
9 kapsamın her birini ayrı fonksiyon yapabilirdim, ama o zaman geliştiricilerin bunları yeniden kullanmak istemesi muhtemeldi. Her adımda, önceki adımda olanlara dair ince varsayımlar vardı; bunları ayrı fonksiyonlara dönüştürmek için varsayımları yeniden gözden geçirmek, genelleştirmek ve her metodun bağımsız çalıştığını doğrulamak gerekirdi. Neredeyse başka hiçbir yerde gerekmeyecek kod için böyle bir maliyete katlanmanın anlamı yoktu
Debug etmek daha zor değildi, uçtan uca testleri de vardı ve ara aşama durumu fonksiyonun dışına sızmıyordu. Hatta zaman içinde 2 başka geliştirici değişikliklere katkı verdi, iyi çalıştı ve yazması da hızlıydı
Doğrusal kod iyi ölçeklenir ve problemi çözer. Her zaman istediğiniz biçim olmayabilir, ama sanıldığından çok daha fazla durumda hayatı çok daha kolaylaştırır
İlk kez 2000 satırlık canavarı gördüklerinde tepki iyi değildi; ama 5 dakika bakınca gerçek bir kusur bulmak zordu ve birkaç test olduğunda geriye, gerçekleşmeyen korkulardan başka bir şey kalmıyordu
Bir noktada o onlarca fonksiyonun yalnızca belirli bir sırayla çağrılması gerektiğini ve her birinin yalnızca bir kez kullanıldığını fark edersiniz. Sonuçta, birinin o fonksiyonları işe yarar şekilde kullanabilmesi için sihirli kombinasyon sırasını bilmesini zorunlu kılmış olursunuz
Devasa doğrusal bir fonksiyonun çoğu zaman daha okunur ve tercih edilir olmasının temel nedeni, birden çok kavram ve ilişkiyi bağlam değiştirmeden tek parça hâlinde aynı anda zihinde tutabilmeyi sağlayarak anlamayı kolaylaştırmasıdır. Bunun uç bir savunucusu K dilinin mucidi Arthur Whitney'dir; tek ekrana olabildiğince çok şey sığdırmak için çok özlü ve başkalarına neredeyse anlaşılmaz görünen kod yazar
Kişisel bir örnek olarak, iş mantığının büyük bir
switchifadesinde yer aldığı devasa Windows mesaj işleme fonksiyonu, yaniWndProc, mesaj handler'larını ayrı fonksiyonlara bölen Visual C++ sürümüne kıyasla okumak, anlamak ve debug etmek açısından çok daha kolaydıBir başka örnek de mikrodenetleyici örnek kodlarında ADC kullanımının tek dosyada tamamen yer aldığı bir sürüm ile
main.c,config.c,interrupts.c,timer.cgibi birden çok dosyaya bölünmüş bir sürüm olmasıydı; 200 satır bile değildi ama ikincisini bağlam geçişleri yüzünden anlamak zorduBu kod parçaları genellikle sınıfın
privatefonksiyonları olur ve durum taşır.privatefonksiyon oldukları için fiilen test etmek de zordurArtık yalnızca bir kez çağrılan ve genellikle yan etkili durumu değiştiren bir sürü
privatefonksiyonunuz olur. Çağıran kodla hemen yan yanaysa basit durumlarda hâlâ okunabilir, ama zamanla biri çağıran fonksiyon ile çıkarılmış fonksiyonun arasına başka fonksiyon eklerO zaman çağrı grafiğine bakmadıkça ya da sınıf dosyasında arama yapmadıkça nereden çağrıldığını bilmediğiniz kod parçaları, farklı yan etkili durumları değiştirmeye başlar
Kodu doğrusal olmayan hâle getirecekseniz, dil destekliyorsa çıkarılmış
privatefonksiyonu en azından çağıran fonksiyonun iç fonksiyonu yapmayı düşünmenizi isterim. Böylece başka yerden çağrılmadığı açık olurGerçek kod tabanlarında bu da ya o ya bu meselesi değil; ikisini birleştirip okunur ve bakımı yapılabilir bir biçime getirme sanatı gibidir
İnsanlar tüm bu dalları test edecek mi? Yoksa sadece bir pizza ekleyen bir test yazıp kabaca çalışıyor mu diye mi bakacak? Dışarıdan birden çok dalı test etmek genellikle zahmetlidir ve küçük, özelleşmiş fonksiyonları test etmekten daha uğraştırıcıdır; bu yüzden ikincisi daha olası görünüyor
“Doğrusal kod ölçeklenmez” sözü aslında bunun tam tersidir. Büyük kod tabanlarında asıl kâbusa dönüşen şey, derinlemesine iç içe geçmiş çağrı yığınlarına sahip küçük ve özlü fonksiyonlardır.
Yeni kodun nereye ekleneceği net değildir; kodun çağrılabileceği tüm yolları izlemek gerektiği için değişikliklerin etkisini anlamanın zorluğu üstel biçimde artar ve yinelenen alt rutinler de ortaya çıkar.
Vakaların %99’unda iyi bir soyutlama yapmış olmazsınız; bu yüzden doğrusal kod yazmak daha iyidir. Şüpheli fonksiyon semantiklerine kıyasla kopyala/yapıştırı tercih ederim.
print_table()eklerseniz, biri onu bulup kendi kodunda kullanır ve kendi kullanım senaryosuna göre çıktıyı ayarlayan küçük bir bayrak ekler.12 ay sonra şöyle bir şeye dönüşür:
print_table(rows,headers = None,is_unicode = False,left_align = False,align = [],remove_emoji = None,max_width = 80,potato_mode = 7,_debug_frontend = not FLAGS.dont_debug,ellipsis_for = 0,no_print = False,)Okunabilirliğin ölçeklenebilirliği etkileyebileceği gerçeğini bir kenara bırakıp iki kavramı birbirine dik kabul edersek, doğrusal kod modüler kod kadar iyi ölçeklenmez. Bu ikili ayrımı bilmek ve duruma göre dikkate almak değerli.
Yine de hâlâ katılmıyorum. Küçük fonksiyon saf fonksiyon ise okunabilirlik sorunu yaratmaz. Bu, duruma dokunmadığı anlamına gelir; koda mantık enjekte etmemeli, bağımlılık enjeksiyonunu ve fonksiyonları başka fonksiyonlara geçirmeyi açıkça en aza indirmelidir.
Yalnızca veri aktaran saf fonksiyonlardan bir pipeline kurarsanız kod hem okunabilir hem de genişletilebilir olur. Tasarım kusurları yüzünden mantığı yeniden yazmak zorunda kalma ihtimali çok azalır; saf fonksiyonları birleştirdiğinizde kod Lego gibi olur. Refactoring de mevcut ilkel öğeleri yeniden düzenleyip yeniden birleştirmeye daha çok benzer.
Örnek kod, en azından pizza metaforunu anlamlı biçimde korumaya çalışsaydı ya da düşük seviyeli Go kodu olmasaydı daha az dikkat dağıtıcı olurdu.
preparebir fonksiyon adı olarak berbat. Deneyimli bir Gopher muhtemelenNewPizzaFromOrdergibi bir ad verirdi.addToppingsi ayrı bir fonksiyon olarak tutmak için bir neden göremiyorum. Mutlaka gerekiyorsa şahsen bunuPizzaüzerindefunc (p *Pizza) WithToppings(topping ...Topping) *Pizza { /* ... */ }gibi bir metot yapardım. Gerçek pizza değiştirilebilir olduğu için metot alıcıyı değiştirir.Her pizza pişirdiğinizde neden yeni bir fırın örneği oluşturulduğunu da anlamıyorum. Mevcut bir fırınla başlayıp
oven.Preheat()yapmalı veoven.Bake(pizza)çağrılmalı. Hatta daha ileri gidipoven.Preheat()in,.Bake()i açığa çıkaran yeni birOventipi döndürmesini sağlayarak ön ısıtma yapmadan pişirme hatasını derleme aşamasında engelleyebilirsiniz. Başka bir yerdeBakerarayüzü olabilir ve ön ısıtmanın pek önemli olmadığı, buna ihtiyaç duymayan birToasterOvenimplementasyonu da bulunabilir.Kodu değiştirmesem bile bildirim sırasını beklenen akışa göre yeniden düzenlerdim. Böylece birbirini çağıran fonksiyonlara göz atarken sayfada aşağı yukarı zıplamak gerekmez.
Zamanım olmadığı için burada duruyorum, ama bu kod “hangisi daha okunabilir” tartışmasını başlatmak için bile zaten çok kötü bir örnek.
John Carmack de neredeyse aynı şeyi söyledi ve o zamandan beri bunu uyguluyorum. Doğrusal kod yürütme sırasını izlediği için doğal olarak okunması kolaydır ve göz sıçramalarını en aza indirir.
Bazı kodların yeniden kullanım için doğrusal olmaması gerekir; o zaman yürütme bir grafa dönüşür. Kod graf yapısındaki yeniden kullanımdan yararlanmıyorsa, tek bir kenarın yeterli olduğu yerde düğüm eklemeye gerek yoktur.
http://number-none.com/blow/blog/programming/2014/09/26/carm...
Bu durumda soldaki kod
pizza.Toppings = get_pizza_toppings(order.kind)gibi olsaydı, ana fonksiyonda pizzayı değiştirme odağı kalacağı için bence daha iyi olurdu.Doğrusal kodun daha okunabilir olduğuna bir ölçüde katılıyorum, ama bu tek başına onu iyi bir kod pratiği yapmaz.
İyi doğrusal kodun daha okunabilir olduğunu düşünüyorum, fakat sürdürülebilirlik ve test edilebilirlik çok daha zayıf oluyor. Onlarca yıllık deneyimim var ve CS öğrencileri için dış değerlendirme de yapıyorum; yıllar boyunca pratikte gördüğüm iyi uygulamalar içinde kesin olan tek şey fonksiyonları küçük tutmak oldu.
Soyutlamayı özellikle sevdiğim de yok, kod tekrarından mutlaka kaçınılması gerektiğini de düşünmüyorum; ama mümkün olduğunca tek amaca yakın fonksiyonlar yazarsanız gelecekteki siz size teşekkür eder.
Örnekteki gibi bir kod 10 yıl boyunca production’da çalışırsa her bölüm değişecektir. Şansınız varsa yorumlar da güncellenir, ama çoğu zaman öyle olmaz. Birim testleri de büyüyüp yönetmesi zorlaştıkça giderek özensizleşir; birileri, değişiklikle açıkça ilişkili görünmeyen test kısımlarını düzeltmeyi unutabilir. Kodun kendisi de zamanla daha az okunur hâle gelmeye çok yatkındır. Bu niyetten ya da beceriksizlikten değil, zaman baskısı gibi insani nedenlerden olur.
Mükemmel bir dünyada kaygıları ayırmaya gerek olmazdı; ama kusurlu bir dünyada yaşıyoruz ve fonksiyonlar ne kadar küçük, sorumlulukları ne kadar az olursa zaman içinde bu kusurlarla baş etmek o kadar kolaylaşır.
Bir nesneyi belirli durumların akışı içinden geçiriyorsanız, bunu parçalara ayırıp geçişleri tiplerle belirtmek ya da tek büyük bir fonksiyon olarak yazmak bence daha iyi. Örneğin
bakePizza,RawPizzaalıpBakedPizzadöndürürse çağrı sırasını derleme zamanında zorunlu kılabilirsiniz.Okunabilirlik, doğruluk ve test edilebilirlik nedeniyle ilkini tercih ederim; ancak çoğu programlama dilinde bir nesnenin tipini değiştirmek için yeni bir nesne oluşturmak gerekir ve bunun çalışma zamanı maliyeti vardır. Sıcak bir kod yolundaysa yerinde değiştirme makuldür; bu durumda da tek bir doğrusal fonksiyonda tutmak daha iyidir.
https://mitpress.mit.edu/9780262045490/
John Carmack’in ilgili e-postası: http://number-none.com/blow/blog/programming/2014/09/26/carm...
Tartışma: https://news.ycombinator.com/item?id=12120752
Kesinlikle katılıyorum. Eskiden karşı kamptaydım.
Buradaki temel gerilim, bir taraftaki davranışın yerelliği ile diğer taraftaki üst düzey “içindekiler tablosu” görünümünü net biçimde gösterme arzusu arasında. Okunabilir kodda yerellik daha önemlidir. Yazıda söylendiği gibi, içindekiler tablosu bakışı bölüm yorumlarıyla yeterince açık hâle getirilebilir.
Doğrusal kodu tercih etmek için daha önemli bir neden de var. Tüm kod tabanında gezinirken “parçalar”, yani fonksiyonlar, sınıflar ya da dilin dayattığı birimler kabaca iş kullanım senaryolarına karşılık geliyorsa bu çok daha kolaydır. Aksi hâlde arama alanı fazla büyür ve bütünü parçalardan kendiniz yeniden kurmanız gerekir. Kod yapısının bu işi sizin yerinize yapması gerekir.
Birden fazla “şey”in hepsi tek bir işle, örneğin kayıt olma ya da satın alma ile ilgiliyse kodda da tek yerde durmaları daha iyidir. Bulmak ve değiştirmek çok daha kolay olur. Yalnızca yeniden kullanım gerektiğinde alt fonksiyonlara bölünmeli; sırf düzenleme amacıyla bölünmemeli.
[0] https://htmx.org/essays/locality-of-behaviour/
En büyük neden durum. Fonksiyon uzadıkça yerel değişkenlerin kapsamı genişler. Fonksiyonun herhangi bir yerinde herhangi bir değişken değiştirilebilir ve veri akışı hemen açık olmaz. Fonksiyon sayısı fazla olduğunda kapsam küçük kalır ve veri akışı daha açık hâle gelir.
Yan etki olarak girintileme de azalır.
Bununla birlikte aşırı küçük fonksiyonları sevmiyorum; çünkü asıl işin nerede yapıldığını bulmak zorlaşır.
Sırayla çalışması gereken, yeniden kullanılamayan 10 adımı olan ve her adımı 100 satır süren bir gün sonu işlemi düşün. Her adım bir öncekiyle benzer ama aynı olmayan verileri kullanıyor. Gerçekten 1000 satırlık tek bir fonksiyonu mu seçersin?
İkisi de doğrusal okunuyor. Küçük fonksiyonların çıkarıldığı sürümde sayfanın üstünde bir içindekiler tablosu var ve adımlar arasındaki veri akışını özetliyor. Tamamını okuyacaksanız çekici bir okuma sırası gibi görünüyor.
Ancak bu okunabilirliği korumak için adımların sırası değiştiğinde fonksiyonların konumunu da taşımak gerekir.
privatefonksiyonlarsa ve yalnızca içindekiler tablosundan çağrılıyorlarsa sorun yok. Fakat hiçbir şey sıranın korunmasını zorunlu kılmıyor; genel okuma akışını düşünmeyi de zorunlu kılmıyor.Fonksiyon yeniden kullanılmaya başladığında çoğu zaman artık doğrusal hâle getirilemez. Bazen insanlar pes edip alfabetik sıralar ya da tamamen rastgele hâle gelir.
Deneyimlerime göre bir kişi koda ne kadar aşinaysa, kodu küçük fonksiyonların içine itmenin doğru yol olduğunu o kadar düşünür.
Zaten o kodun zihinsel modelini kurmuş olduğu için, onun gözünde en temiz uygulama satır sayısı çok az olan uygulamadır.
Ama sıradaki kişi geldiğinde, aynı zihinsel modeli başlangıçtaki bağlam olmadan kurmak için oradan oraya gidip gelirken kafasındaki stack’i push/pop yapmak zorunda kalır; bu da çok daha zordur.
Örneğin kullandığınız dilin standart kütüphane kaynak kodunu ne sıklıkla okursunuz? Neredeyse hiç okumazsınız; genelde metot imzasına bakar, biraz karmaşıksa ya da yeniyse dokümantasyonu okursunuz.
Bir arayüzün özü, metodun nasıl uygulandığıyla değil, ne yaptığıyla ilgilenmenizi sağlamaktır. Bu da bağlam, adlandırma ve dokümantasyonun birleşimiyle açıklanır. Ama birçok geliştirici bunu anlamaz ya da umursamaz; bu yüzden doğrusal ya da modüler olması fark etmeksizin anlamsız kod yazar.
Örneğin bir servis sınıfında bir metodu çağırıp bir veri almanız, başka bir metotla başka bir veri almanız, üçüncü bir metotla da önceki ikisiyle birleştirilmesi gereken veriyi almanız gerekiyorsa, o servisin anlamı nedir? İç karmaşıklığı tamamen dışarıya açmış olursunuz.
Küçük metotları zorunlu kılalım demiyorum. Yalnızca bir kez çağrılan, çok spesifik bir iş yapan ve doğru sırayla çağrılması gereken 5 satırlık 20 fonksiyonun bir anlamı yoktur. Bu temiz kod değil, daha çok cargo cult programming’e yakındır.
Önemli olan, hem yeni ekip üyeleri hem de deneyimli ekip üyeleri için anlamlı olan, akıl yürütmesi kolay ve karmaşıklığı uygun yerde gizleyecek şekilde doğru soyutlamayı yapmaktır. Kolay değil ama mümkün.
Oğlum yeterince zeki olmasına rağmen okulda zorlanıyordu; birkaç uzmandan biri, okulun genel olarak aşağıdan yukarı öğrettiğini, ama oğlumun çok belirgin biçimde yukarıdan aşağı öğrenen biri olduğunu açıklamıştı. Ayrıntılara girmeden önce önce genel çerçeveye ihtiyaç duyuyor; başka insanlar ise önce ayrıntıları kavrayıp sonra genel çerçeveyi birleştirmek zorunda. Okul genelde ikinci gruba göre öğretir.
Programcılar arasında da benzer bir fark olabilir.
Önceki geliştirici
BakePizzafonksiyonunu yazdıysa pizzanın düzgün pişeceğini varsayıp sonraki satıra geçebilirsiniz. Restoranın nasıl işlediğini anlamaya çalışırken fırın sıcaklığı gibi ayrıntılara takılırsanız, restoranın nasıl döndüğünü de anlayamaz, doğru fırın sıcaklığını da unutursunuz.Editörde fonksiyonları geçici olarak inline eden bir toggle olmalı. Artık ileri geri gitmeye gerek kalmaz.