İşlev uzunluğu bir programcının verimliliğini etkiler mi? Öyleyse, verimlilik kaybını önlemek için iyi bir maksimum hat sayısı nedir?
Bu çok tartışılan bir konu olduğundan, lütfen talebi bazı verilerle yedekleyin.
İşlev uzunluğu bir programcının verimliliğini etkiler mi? Öyleyse, verimlilik kaybını önlemek için iyi bir maksimum hat sayısı nedir?
Bu çok tartışılan bir konu olduğundan, lütfen talebi bazı verilerle yedekleyin.
Yanıtlar:
1970 yılında bu çılgın rakete girdiğimden beri, bir sayfadan fazla yazdırılması gereken tam bir modül gördüm (yaklaşık 60 satır). Daha uzun süren birçok modül gördüm.
Bu konuda daha uzun modüller yazdım, ancak bunlar genellikle büyük anahtar ifadeleri olarak yazılmış büyük sonlu durumlu makinelerdi.
Sorunun bir kısmı, programcılara bugünlerde işleri modüler hale getirmediği anlaşılıyor.
Dikey alan israfını maksimize eden kodlama standartları da sorunun bir parçası gibi görünmektedir. ( Gerald Weinberg'in " Bilgisayar Programcılığının Psikolojisi " ni okuyan bir yazılım yöneticisi ile henüz görüşmedim . Weinberg, çok sayıda çalışmanın programcının kavranmasının esasen programcının herhangi bir anda görebilecekleri ile sınırlı olduğunu gösterdiğini belirtti. programcının bir sayfayı kaydırması veya bir sayfayı çevirmesi gerekir; anlamaları önemli ölçüde düşer: hatırlamaları ve soyutlamaları gerekir.)
FORTH'tan elde edilen iyi belgelenmiş programcı üretkenlik kazanımlarının çoğunun kaynak kodu için FORTH "blok" sisteminden kaynaklandığına ikna oldum : modüller mutlak maksimum 16 satır 64 karakterle sınırlıydı. Sonsuz bir faktör olabilir, ancak hiçbir koşulda 17 satırlık bir rutin yazamazsınız.
Kullandığınız dile, fakat genel olarak (ve kişisel zevkime göre):
Daha fazla ise, o zaman daha sonra gelip tekrar çalışmam gereken bir şey.
Ancak gerçekçi olarak , bir şeyi teslim etmeniz gerektiğinde ve bu şekilde tükürme anında daha mantıklı gelmesi gereken her boyut, bazen göndermeden önce birisinin incelemesini daha da kolaylaştırır. (ama yine de daha sonra geri almak).
(Son zamanlarda ekibim kod temeli üzerinde bir program yürüttü: sınıfı 197 yöntemle, diğeri sadece 3 yöntemle bulduk ama bunlardan biri 600 satırdı. Sevimli oyun: 2 kötünün en kötüsü nedir?)
Şimdi daha fazla zen cevabı için ... Genel olarak, bir veya iki büyük adamdan alıntı yapmak için iyi bir uygulama (TM) olarak kabul edilir, işte burada:
Her şey mümkün olduğunca basit yapılmalı, ancak basitleştirilmemelidir. - A. Einstein
Artık nihayet ekleyecek bir şey olmadığında değil, alınacak bir şey olmadığında da elde edilir. - A. de Saint Exupéry
Buna ek olarak, işlevleriniz niyetlerini açıklayan net isimlere sahip olmalıdır. Yorumlar hakkında, genellikle bir işlev içinde yorum yapmam:
Her işlevin en üstünde bir açıklama bloğu (açıklama gerektiren) yeterlidir. Eğer fonksiyonunuz küçükse ve fonksiyon isimleri yeterince açıksa, neye ulaşmak istediğinizi ve nedenini söylemelisiniz. Satır içi yorumları yalnızca bazı dillerde alanlar için veya blok açıkken, amaç belirsizse 25-35 satır kurallarını kıran işlevler için kullanırım. İstisnai durumlar ortaya çıktığında kodun içindeki bir blok yorumunu kullanırım (örneğin, herhangi bir şey yapmak istemediğiniz veya bir şey yapmak istemediğiniz bir alıcı bloğu, nedenini söyleyen bir yorum yapmalıdır).
Daha fazla bilgi için, lütfen okuyun cevabım üzerine Tarzı ve yorumlama kod öneriler
tt
üretmek için çoğunlukla kullanıyorum , ancak bazen uzun zamandır bir eşek işlevine (ya da uzun eşek işlevine) sıkı sıkıya bağlı kalıyorsunuz.
Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
, tamamen aynı olduğu açıktır. (Bunun sadece bir örnek olduğuna dikkat edin; bu tür işlevler zaman zaman ortaya çıkar)
Bence her fonksiyon mümkün olduğunca küçük olmalıdır. Her fonksiyon sadece bir şey yapmalı ve iyi yapmalı. Bu, maksimum uzunluk sorusuna gerçekten cevap vermiyor, ancak işlevlerin uzunluğu hakkındaki hislerim daha fazla.
Bob Amca'nın sözlerini kullanmak için, "Artık çekemezsiniz. Çıkarın.
Bir binanın maksimum yüksekliği ne olmalıdır? Yapının bulunduğu yere veya olmasını istediğiniz yüksekliğe bağlıdır.
Farklı şehirlerden gelen farklı insanlardan farklı cevaplar alabilirsiniz.
Bazı script fonksiyonları ve çekirdek kesme işleyicileri çok uzun.
Benim için çalışan bir yöntem şudur: Daha uzun bir fonksiyonun bir parçası olabilir mi, mantıklı bir isim verebilirim. Bir yöntemin uzunluğunun iyi adlandırma kadar önemli olmadığını düşünüyorum. Yöntem, adının söylediğini yapmalı, daha fazla ve daha az değil. Ve iyi bir isim verebilmelisin. Yönteminizi iyi adlandıramazsanız, kod muhtemelen bir araya getirilmiş olması iyi değildir.
Yapması gerekeni yapması gerektiği sürece, ama yapması gerekmiyor.
Bence bir takas var. Çok sayıda kısa yönteminiz varsa, bunları uzun bir yöntemden daha çok ayıklamak zordur. Bir yöntem çağrısını izlemek için editörün etrafında 20 veya 30 farklı kez atlamak zorunda kalırsanız, 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 genellikle daha kolaydır.
Asıl soru, neden öğelerin farklı yöntemlerde olması gerektiğidir ve yukarıda verilen cevap kodun yeniden kullanımıdır. Eğer kodu tekrar kullanmıyorsanız (ya da bilmiyorsanız), onu takip etmek için tek bir devin içine bırakmak kolay olabilir ve sonra tekrar kullanmanız gerektiğinden, tekrar kullanılması gereken parçaları ayırın. daha küçük yöntemlere kullanmak.
Gerçekte, iyi yöntem tasarımının bir parçası fonksiyonel olarak uyumlu yöntemler yapmaktır (temel olarak bir şey yaparlar). Yöntemlerin uzunluğu önemli değil. Bir işlev iyi tanımlanmış bir şey yaparsa ve iyi bir yöntemden 1.000 satır ise Bir işlev 3 veya 4 şey yapar ve sadece 15 satır ise, o zaman kötü bir yöntemdir ...
Tüm işlevi aynı anda görebilirsem ne yaptığımı takip etmeyi daha kolay buluyorum. İşte size fonksiyon yazmayı tercih ediyorum:
İşlevleri nadiren bundan daha uzun yazıyorum. Bunların çoğu dev C / C ++ switch ifadeleridir.
Soru, bir fonksiyonun kaç şeyi yapması gerektiğidir. Ve genellikle, "bir" şeyi yapmak için 100 satıra ihtiyaç duymanız nadirdir. Yine de bu, koda hangi seviyeden bakıyor olduğunuza bağlı: Bir şifre mi var? Yoksa şifreyi toplamak ve saklamak bir şey midir?
Diyelim ki, bir işlev olarak şifre kaydetmeye başlayın. Bu karmaşanın farklı olduğunu düşündüğünüzde ve kodu yeniden uygularsanız. Ben hiçbir şekilde uzman bir programcı değilim, ancak IMHO, fonksiyonların tümünün küçük bir şekilde başlaması, işlevleriniz ne kadar atomik olursa, kodun tekrar kullanma şansı o kadar yüksek, hiçbir zaman aynı değişikliği yapmak zorunda değilsiniz. , vb.
1000'den fazla satır çalıştıran SQL saklı yordamlar gördüm . Depolanan işlemlerin satır sayısı da 50'den az mı? Bilmiyorum, ama kodu okutuyor, cehennem. Sadece yukarı ve aşağı kaydırmaya devam etmek zorunda kalmazsınız, aynı zamanda "bu doğrulama yapar1", "veritabanındaki bu güncellemeler" vb. Gibi bir satır kod vermeniz gerekir - programcının yapması gereken bir çalışma.
Gönderen Cyclomatic karmaşıklık (Vikipedi):
Kaynak kodun bir bölümünün döngüsel karmaşıklığı, kaynak kod boyunca doğrusal olarak bağımsız yol sayısının sayımıdır.
Bu sayıyı 10'un altında tek bir yöntemle tutmanızı öneririm. 10'a çıkarsa, tekrar etmenin zamanı geldi.
Kodunuzu değerlendirebilen ve size döngüsel bir karmaşıklık numarası verebilecek araçlar var.
Bu araçları inşa hattınıza entegre etmeye çalışmalısınız.
Kelimenin tam anlamıyla bir yöntem büyüklüğü kovalamayın, ancak karmaşıklığına ve sorumluluklarına bakmaya çalışın. Birden fazla sorumluluğu varsa, muhtemelen yeniden faktör almak iyi bir fikirdir. Siklomatik karmaşıklığı artarsa, muhtemelen yeniden etken olma zamanı gelmiştir.
Size benzer geri bildirimler veren başka araçlar da olduğundan kesinlikle eminim, ancak henüz bu konuda inceleme şansım olmadı.
Genellikle, yöntemleri / işlevlerimi 1680x1050 monitörün ekranına sığacak şekilde tutmaya çalışırım. Uygun değilse, görevi çözmek için yardımcı yöntemler / işlevler kullanın.
Hem ekranda hem de kağıda okunabilirliğe yardımcı olur.
Bazı fonksiyonlar kendiliğinden karmaşık algoritmalar uygular ve bunları kısaltmak için yapılan girişimler yeni, daha kısa fonksiyonlar arasındaki etkileşimi netleştirir, böylece net sonuç basitlikte bir azalma olmaz. Ayrıca, bir işlevin sadece "bir şeyi" yapması gerektiği fikrinin iyi bir rehber olduğuna inanmıyorum, çünkü yüksek bir soyutlama seviyesindeki "bir şey" daha düşük bir seviyede "birçok şey" olabilir.
Bana göre, eğer uzunluğu şu anda ince DRY ihlallerine neden oluyorsa, işlev kesinlikle çok uzundur ve işlevin bir kısmını yeni bir işleve veya sınıfa çıkarmak bunu çözebilir. Durum böyle değilse işlev çok uzun olabilir, ancak kodun yol boyunca öngörülebilir bir değişim karşısında faydalı olacak şekilde daha modüler olmasını sağlayacak bir işlev veya sınıf kolayca çıkarılabilir.
Doğru şekilde optimize edilebilecek kadar kısa
Yöntemler tam olarak bir şeyi yapacak kadar kısa olmalıdır. Bunun nedeni basittir: bu nedenle kodunuz doğru şekilde optimize edilebilir.
Java veya C # gibi bir JIT dili ile, JIT-derleyicisinin hızlı bir şekilde kod üretebilmesi için yöntemlerin basit olması önemlidir. Daha uzun, daha karmaşık yöntemler doğal olarak daha fazla JIT zamanı gerektirir. Ayrıca, JIT derleyicileri yalnızca bir avuç optimizasyon sunar ve yalnızca en basit yöntemler bundan yararlanır. Bu gerçek bile Bill Wagner'in Etkili C # ' sında çağrıldı .
Düşük seviyeli bir dilde, C veya C ++ gibi, kısa yöntemlere (belki bir düzine kadar çizgi) sahip olmak da önemlidir, çünkü bu şekilde yerel değişkenleri bir kayıt yerine RAM'de saklama gereksinimini en aza indirirsiniz. (Aka 'Spilling Register'.) Ancak, bu yönetilmeyen durumda, her bir işlev çağrısının göreceli maliyetinin oldukça yüksek olabileceğini unutmayın.
Hatta Ruby veya Python gibi dinamik bir dilde bile kısa yöntemlere sahip olmak, derleyici optimizasyonlarında da yardımcı olur. Dinamik bir dilde 'dinamik' bir özellik ne kadar iyi olursa, onu o kadar zorlaştırır. Örneğin, X alan ve bir Int, Float veya String döndüren uzun bir yöntem muhtemelen her biri yalnızca tek bir tür döndüren üç ayrı yöntemden çok daha yavaş çalışacaktır. Bunun nedeni, derleyicinin fonksiyonun ne tür döneceğini tam olarak bilmesi durumunda, işlev çağrısı sitesini de optimize edebilmesidir. (Örneğin, tür dönüştürmeleri denetlemiyor.)
Bu kodda ne olduğuna çok bağlı.
Hiçbir problem yaşamadığım binlerce satırlık bir rutin gördüm. Devasa bir anahtar ifadesiydi, hiçbir seçenek bir düzine çizgiyi geçmedi ve herhangi bir seçenekteki tek kontrol yapısı tek bir döngü oldu. Bugünlerde nesnelerle yazılmış olabilirdi ama bu o zamanlar bir seçenek değildi.
Ayrıca önümdeki bir anahtardaki 120 çizgiye bakıyorum. Hiçbir durum 3 satırı geçemez - bir bekçi, bir görev ve mola. Bir metin dosyasını ayrıştırıyor, nesneler olasılık değil. Herhangi bir alternatifi okumak zor olabilir.
Çoğu derleyici bir işlevin uzunluğunu dikkate almaz. Bir işlev işlevsel olmalı, ancak insanların anlaşılması, değiştirilmesi ve yeniden kullanımı kolay olmalıdır. Size en uygun uzunluğu seçin.
Genel kural, bir fonksiyonun ekrana sığması gerektiğidir. Bunu ihlal etmeye meyilli bulduğum sadece üç vaka var:
1) Sevk 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 ilgilenirken ara sıra gönderim işlevlerini göreceksiniz.
2) Hedefe ulaşmak için çok fazla adım atmış olan ve adımların iyi bir alt bölünmeye sahip olmadığı işlevler. Sırayla diğer fonksiyonların uzun bir listesini çağıran bir fonksiyonla son buluyorsunuz.
3) # 2 gibi, ancak bireysel adımların o kadar küçük olduğu, ayrı olarak çağrılmak yerine basitçe çizildiği.
Belki fonksiyon uzunluğu o kadar iyi bir ölçüt değildir. Siklomatik karmaşıklığı , yöntemlerde de kullanmaya çalışıyoruz ve gelecekteki kaynak kontrollerinden biri, sınıflar ve yöntemlerdeki siklomatik karmaşıklığın X'ten düşük olması gerektiği kurallarını denetliyor.
Yöntemler için, X, 30'a ayarlanır ve bu oldukça sıkıdır.