İşlev uzunluğu bir programcının verimliliğini etkiler mi? Öyleyse, üretkenlik kaybını önlemek için iyi bir maksimum hat sayısı nedir?
Bu çok tartışılan bir konu olduğundan, lütfen iddiayı bazı verilerle yedekleyin.
1970'de bu çılgın rakete başladığımdan beri, gerçekten gerekli birden fazla basılı sayfa (yaklaşık 60 satır) olmak için tam olarak bir modül gördüm. Daha uzun modüller gördüm.
Bu nedenle, daha uzun modüller yazdım, ancak genellikle büyük anahtar ifadeleri olarak yazılan büyük sonlu durum makineleriydi.
Sorunun bir kısmı, bugünlerde programcılara modülerleştirmeyi öğretmedikleri gibi görünüyor.
Dikey alan israfını en üst düzeye çıkaran kodlama standartları da sorunun bir parçası gibi görünmektedir. ( henüzGerald Weinberg 's " Bilgisayar Programlama Psikolojisi " yazan bir yazılım yöneticisiyle tanıştım. Weinberg, çoklu çalışmaların programcı kavrayışının esasen programcının herhangi bir anda görebileceği ile sınırlı olduğunu gösterdiğine dikkat çekiyor. Programcı bir sayfayı kaydırmak veya çevirmek zorundaysa, kavrayışları önemli ölçüde düşer: hatırlamaları ve özetlemeleri gerekir.)
İyi belgelenmiş programcı üretkenliğinin çoğunun ILERI 'dan kaynak kod için FORTH "blok" sistemine bağlı olduğuna ikna oldum: modüller zor- maksimum 64 karakterlik 16 satırla sınırlıdır. Sonsuz faktör olabilir, ancak hiçbir koşulda hiçbir şekilde yapamazsınız 17 satırlık bir rutin yazıyorsunuz.
Kullandığınız dile bağlıdır, ancak genel olarak (ve kişisel zevkime göre):
Eğer daha fazlaysa, daha sonra geri dönüp yeniden çalışmam gereken bir şey.
Ancak gerçekçi olarak , bir şey teslim etmeniz gerektiğinde olması gereken herhangi bir boyut ve şu anda onları tükürmenin daha mantıklı olması, bazen birisinin göndermeden önce gözden geçirmesi daha da kolaydır. (ancak yine de daha sonra geri dönün).
(Son zamanlarda ekibim kod tabanımızda bir program yürüttü: 197 yöntemle sınıf ve sadece 3 yöntemle başka bir sınıf bulduk, ancak bunlardan biri 600 satırdı. Sevimli oyun: 2 kötülüğün daha kötüsü nedir?)
Şimdi daha fazla zen cevabı için ... Genel olarak bir ya da iki büyük adamı alıntılamak iyi bir uygulama olarak kabul edilir, işte burada:
Buna bir ek olarak, işlevlerinizin amaçlarını açıklayan net isimleri olmalıdır. Yorumlarla ilgili olarak, genellikle bir fonksiyonun içinde yorum yapmam:
Her bir işlevin üstündeki (açıklama gerektiren) bir yorum bloğu yeterlidir. İşleviniz küçükse ve işlev adları yeterince açıksa, neyi başarmak istediğinizi ve nedenini söylemeniz gerekir. Yalnızca bazı dillerdeki alanlar için veya satır başlangıcında satır içi yorumları, amaç belirsizse 25-35 satır kurallarını ihlal eden işlevler için kullanırım. İstisnai durumlar oluştuğunda kod içinde bir blok yorum kullanıyorum (ihtiyacınız olmayan veya herhangi bir şey yapmak istemediğiniz bir catch bloğu, örneğin nedenini söyleyen bir yorum olmalıdır).
Bence her fonksiyon mümkün olduğunca küçük olmalıdır. Her fonksiyon sadece bir şey yapmalı ve iyi yapmalıdır. Bu, maksimum uzunluk sorusuna gerçekten cevap vermiyor, ama daha çok işlevlerin uzunluğu hakkındaki duygularım.
Bob Amca'nın sözlerini kullanmak için "Artık daha fazla çıkaramayacak kadar çıkar. Düşene kadar çıkar."
Bir binanın maksimum yüksekliği ne olmalıdır? Yapının nerede olduğuna veya olmasını istediğiniz yüksekliğe bağlıdır.
Farklı şehirlerden gelen farklı insanlardan farklı yanıtlar alabilirsiniz.
Bazı kod işlevleri ve çekirdek kesme işleyicileri çok uzun.
Benim için çalışan bir yöntem: Daha uzun bir işlevin bir parçası olabilir miyim mantıklı bir isim vermek. Bir yöntemin uzunluğunun iyi adlandırma kadar önemli olmadığını düşünüyorum. Yöntem adın söylediklerini yapmalı, ne daha fazla ne de daha az. Ve iyi bir isim verebilmelisin. Yönteminizi iyi adlandıramazsanız, kod muhtemelen iyi bir araya getirilmemiştir.
Yapması gerekeni yapmak zorunda olduğu sürece, ama artık değil.
Bence bir değiş tokuş var. Çok sayıda kısa yönteminiz varsa, bunları ayıklamak genellikle bir uzun yöntemden daha zordur. Bir yöntem çağrısını izlemek için düzenleyicinin 20 veya 30 farklı kez atlamanız gerekiyorsa, hepsini kafanızda tutmak zor olacaktır. Bu arada, iyi yazılmış bir net yöntem varsa, 100 satır olsa bile, kafanızda tutmak daha kolaydır.
Asıl soru, öğelerin neden farklı yöntemlerde olması gerektiğidir ve yukarıda verilen cevap kodun yeniden kullanılmasıdır. Kodu tekrar kullanmıyorsanız (veya bilmiyorsanız), onu takip etmek kolay bir devde bırakmanız mantıklı olabilir ve daha sonra tekrar kullanmanız gerektiğinde, daha küçük yöntemlerle.
Gerçekte, iyi yöntem tasarımının bir parçası işlevsel olarak uyumlu yöntemler yapmaktır (aslında bir şey yaparlar). Yöntemlerin uzunluğu önemli değil. Bir işlev iyi tanımlanmış bir şey yaparsa ve iyi bir yöntem olduğundan 1000 satırsa. Bir işlev 3 veya 4 şey yaparsa ve sadece 15 satırsa, o zaman kötü bir yöntemdir ...
Siklomatik karmaşıklık (Wikipedia):
Kaynak kodun bir bölümünün siklomatik karmaşıklığı, kaynak kodu üzerinden doğrusal olarak bağımsız yolların sayısıdır.
Bu sayıyı tek bir yöntemle 10'un altında tutmanızı öneririz. 10'a ulaşırsa, o zaman yeniden çarpanlarına ayırma zamanı.
Kodunuzu değerlendirebilecek ve size siklomatik bir karmaşıklık numarası verebilecek araçlar vardır.
Bu araçları yapı hattınıza entegre etmeye çalışmalısınız.
Kelimenin tam anlamıyla bir yöntem boyutunu kovalamayın, ancak karmaşıklığına ve sorumluluklarına bakmaya çalışın. Birden fazla sorumluluğu varsa, o zaman yeniden çarpanlara ayırmak iyi bir fikir olabilir. Eğer siklomatik karmaşıklığı artarsa, muhtemelen yeniden çarpanlarına ayırma zamanı gelmiştir.
Size benzer geri bildirimler veren başka araçlar olduğundan oldukça eminim, ancak henüz buna bakma şansım olmadı.
Benim için bir işlev olması gereken herhangi bir uzunluktur. Çoğu zaman bölmek ne zaman yeniden kod kullanmak olacaktır.
Temel olarak, 'yüksek uyum, düşük bağlantı' prensibine bağlı kalacağım ve uzunluk konusunda herhangi bir kısıtlama yok.
Soru, bir işlevin kaç şey yapması gerektiğidir. Ve genellikle, "bir" şey yapmak için 100 satıra ihtiyaç duymanız nadirdir. Yine bu, koda baktığınız seviyeye bağlıdır: Bir şifre hashing bir şey mi? Yoksa parola karma ve kaydetmek bir şey mi?
Ben söyleyebilirim, bir işlev olarak şifre kaydetme ile başlayın. Karma işlemin farklı olduğunu düşündüğünüzde ve kodu yeniden düzenlediğinizde. Hiçbir şekilde uzman bir programcı değilim, ancak IMHO, işlevlerin tüm fikri küçük başlar, işlevleriniz ne kadar atomik olursa, kodun yeniden kullanım şansı o kadar yüksektir, asla aynı değişikliği birden fazla yerde yapmak zorunda değildir , vb.
1000 satır üzerinde çalışan SQL saklı yordamlar gördüm. Saklı yordamların satır sayısı da 50'den az mı? Bilmiyorum, ama kodu okumayı yapar, cehennem. Sadece yukarı ve aşağı kaydırmaya devam etmekle kalmaz, aynı zamanda birkaç kod satırına "bu doğrulama1", "veritabanındaki bu güncellemeler" vb. Gibi bir ad vermeniz gerekir - programcının yapması gereken bir çalışma.
Tüm işlevi bir kerede görebiliyorsam ne yaptığımı takip etmeyi daha kolay buluyorum. İşte ben işlevleri yazmak için nasıl:
Nadiren bundan daha uzun fonksiyonlar yazıyorum. Bunların çoğu dev C/C++ anahtar ifadeleridir.
Doğru şekilde optimize edilecek kadar kısa
Yöntemler tam olarak bir şey yapacak kadar kısa olmalıdır. Bunun nedeni basittir: böylece kodunuz uygun şekilde optimize edilebilir.
Java veya C # gibi JIT-dilinde bir dilde, JIT-derleyicisinin hızlı bir şekilde kod üretebilmesi için yöntemlerinizin basit olması önemlidir. Daha uzun, daha karmaşık yöntemler doğal olarak daha fazla JIT süresi gerektirir. Ayrıca, JIT derleyicileri sadece birkaç optimizasyon sunar ve bundan sadece en basit yöntemler faydalanır. Bu gerçek, Bill Wagner'in Etkili C # içinde bile çağrıldı.
C veya C++ gibi daha alt düzey bir dilde, kısa yöntemlere (belki de bir düzine hatta) sahip olmak da önemlidir çünkü bu şekilde yerel değişkenleri bir kayıt yerine RAM içinde saklama ihtiyacını en aza indirirsiniz . (Aka 'Dökülmeyi Kaydet') Ancak bu yönetilmeyen durumda, her işlev çağrısının göreceli maliyetinin oldukça yüksek olabileceğini unutmayın.
Ve Ruby veya Python gibi dinamik bir dilde bile, kısa yöntemlere sahip olmak derleyici optimizasyonlarında da yardımcı olur. Dinamik bir dilde ne kadar 'dinamik' bir özellik varsa, optimizasyonu o kadar zordur. Örneğin, bir X alan ve bir Int, Float veya String döndürebilen uzun bir yöntem, her biri yalnızca tek bir tür döndüren üç ayrı yöntemden çok daha yavaş çalışacaktır. Bunun nedeni, derleyicinin işlevin tam olarak ne tür döndüreceğini biliyorsanız, işlev çağrı sitesini de optimize edebilmesidir. (Örneğin, tür dönüşümlerini kontrol etmiyor.)
Tipik olarak, yöntemlerimi/işlevlerimi 1680x1050 monitörlerin ekranına sığmaya çalışırım. Uygun değilse, görevi çözümlemek için yardımcı yöntemleri/işlevleri kullanın.
Hem ekranda hem de kağıtta okunabilirliğe yardımcı olur.
Bazı işlevler, doğası gereği karmaşık olan algoritmalar uyguladığından ve bunları daha kısa yapma girişimlerinden herhangi biri için sabit bir çizgi sınırı koymuyorum, net sonucun basitlikte bir azalma olmayacak şekilde yeni, daha kısa işlevler arasındaki etkileşimleri o kadar karmaşık hale getirecektir. Ayrıca, bir işlevin yalnızca "tek bir şey" yapması gerektiği fikrinin iyi bir rehber olduğuna inanmıyorum, çünkü yüksek düzeyde soyutlamadaki "tek bir şey" daha düşük bir seviyede "birçok şey" olabilir.
Bana göre, eğer bir işlev uzunluğu DRY şu anda ince ihlallere neden oluyorsa kesinlikle çok uzundur ve işlevin bir kısmını yeni bir işleve veya sınıfa çıkarmak bunu çözebilir. bu durumda değilse, ancak kodun yolda öngörülebilen değişiklik karşısında faydalı olabilecek bir şekilde daha modüler olmasını sağlayacak bir işlev veya sınıf kolayca çıkarılabilir.
Kodda ne olduğuna çok bağlı.
Hiç sorun yaşamadığım bin satırlık bir rutin gördüm. Büyük bir anahtar deyimiydi, hiçbir seçenek bir düzine çizgiyi aşmadı ve herhangi bir seçenekteki tek kontrol yapısı tek bir döngü idi. Bu günlerde nesnelerle yazılmış olurdu ama o zamanlar bu bir seçenek değildi.
Ayrıca önümdeki bir anahtarda 120 satıra bakıyorum. Hiçbir dava 3 çizgiyi aşmaz - bir bekçi, bir ödev ve ara. Bir metin dosyasını ayrıştırıyor, nesneler bir olasılık değil. Herhangi bir alternatifin okunması daha zor olurdu.
Çoğu derleyici bir işlevin uzunluğunu dikkate almaz. Bir işlev işlevsel olmalı, ancak hem anlaşılması, değiştirilmesi hem de insanlara yeniden kullanımı kolay olmalıdır. Size en uygun uzunluğu seçin.
Belki fonksiyon uzunluğu o kadar iyi bir ölçüm değildir. Yöntemlerde de siklomatik karmaşıklık kullanmaya ve sınıflar ve yöntemler üzerindeki siklomatik karmaşıklığın X'ten düşük olması gerektiğine ilişkin gelecekteki kaynak kontrolü giriş kurallarından birini kullanmaya çalışıyoruz.
Yöntemler için, X 30'a ayarlıdır ve bu oldukça sıkıdır.
Genel kuralım bir fonksiyonun ekrana sığması gerektiğidir. Bunu ihlal etme eğiliminde olduğunu tespit ettiğim sadece üç vaka var:
1) Dağıtım fonksiyonları. Eski günlerde bunlar yaygındı, ancak çoğu bugünlerde nesne mirası ile değiştirildi. Nesneler yalnızca programınızın içinde çalışır ve bu nedenle başka bir yerden gelen verilerle uğraşırken zaman zaman gönderim işlevleri görürsünüz.
2) Bir hedefe ulaşmak için bir sürü adım yapan ve adımların iyi bir alt bölümden yoksun olduğu işlevler. Sonunda, diğer işlevlerin uzun bir listesini sırayla çağıran bir işlev elde edersiniz.
3) # 2 gibi, ancak münferit adımların o kadar küçük olduğu yerlerde, ayrı olarak adlandırılmak yerine basitçe satır içine alınırlar.