it-swarm.asia

Bir işlev çok kısa olabilir mi?

Kendimi aynı mantığı bir kereden fazla yazarken bulduğumda, genellikle bir işleve yapışırım, bu yüzden uygulamamda bu mantığı korumak zorunda olduğum tek bir yer vardır. Bir yan etkisi ben bazen gibi bir veya iki hat fonksiyonları ile sonuçlanmasıdır:

function conditionMet(){
   return x == condition;
}

OR

function runCallback(callback){
   if($.isFunction(callback))
     callback();
}

Bu tembel mi yoksa kötü bir uygulama mı? Sadece soruyorum çünkü bu çok küçük sayıda mantık için çok sayıda fonksiyon çağrısına neden oluyor.

128
Mark Brown

Hehe, oh Bay Brown, tanıştığım tüm geliştiricileri işlevlerini bu kadar küçük tutmaya ikna edebilsem, inan bana, yazılım dünyası daha iyi bir yer olurdu!

1) Kod okunabilirliğiniz on kat artar.

2) Okunabilirlik nedeniyle kodunuzun sürecini anlamak çok kolay.

3) DRY - Kendinizi Tekrar Etmeyin - Buna çok iyi uyuyorsunuz!

4) Test edilebilir. Küçük fonksiyonların test edilmesi, çok sık gördüğümüz 200 hat yönteminden bir milyon kat daha kolaydır.

Oh ve performans açısından "işlev atlama" konusunda endişelenmeyin. "Release" derlemeleri ve derleyici optimizasyonları bizim için bununla çok iyi ilgilenir ve performans sistem tasarımında başka bir yerde zamanın% 99'udur.

Bu tembel mi? - Tam tersi!

Bu kötü bir uygulama mı? - Kesinlikle hayır. Çok yaygın olan katran topları veya "Tanrı Nesneleri" ne göre bu yöntem yapma yöntemini çekmek daha iyidir.

İyi işi devam et dostum;)

166
Martin Blore

Ya bir refactored yöntemi çok kısa olduğunu söyleyebilirim:

  • İlkel bir işlemi, bir yöntem yapmaktan başka bir amaç için çoğaltır:

Ör:

boolean isNotValue() {
   return !isValue();
}

veya...

  • Kod yalnızca bir kez kullanılır ve amacı bir bakışta anlaşılması kolaydır.

Ör:

void showDialog() {
    Dialog singleUseDialog = new ModalDialog();
    configureDialog(singleUseDialog);
    singleUseDialog.show();
}

void configureDialog(Dialog singleUseDialog) {
    singleUseDialog.setDimensions(400, 300);
}

Bu geçerli bir desen olabilir, ancak onu geçersiz kılmayı veya bu kodu başka bir yerde yeniden kullanmayı amaçlamamış olsaydım, bu örnekte, sadece configureDialog () yöntemini satır içi yapardım.

64
RMorrisey

Bir işlev çok kısa olabilir mi? Genel olarak hayır.

Aslında bunu sağlamanın tek yolu:

  1. Tasarımınızdaki tüm sınıfları buldunuz
  2. Fonksiyonlarınız sadece bir şey yapıyor.

Fonksiyonlarınızı mümkün olduğunca küçük tutmaktır. Başka bir deyişle, daha fazla ayıklamadığınız sürece işlevleri işlevlerinizden ayıklayın. Buna "Düşene kadar çıkar" diyorum.

Bunu açıklamak için: İşlev, değişkenlerle iletişim kuran işlevsellik parçalarına sahip bir kapsamdır. Sınıf, değişkenlerle iletişim kuran işlevsellik parçalarına sahip bir kapsamdır. Böylece uzun bir işlev her zaman küçük yöntemle bir veya daha fazla sınıfla değiştirilebilir.

Ayrıca, başka bir işlevi çıkarmanıza izin verecek kadar büyük bir işlev birden fazla şey yapıyor tanım gereği. Yani can başka bir işlevi çıkarırsanız, gerekir bu işlevi ayıklayın.

Bazı insanlar bunun fonksiyonların çoğalmasına yol açacağından endişe ediyor. Haklılar. Olacak. Bu aslında iyi bir şey. İyi çünkü fonksiyonların isimleri var. İyi adlar seçerken dikkatli olursanız, bu işlevler diğer kişileri kodunuz aracılığıyla yönlendiren işaret yazıları olarak işlev görür. Gerçekten de, iyi adlandırılmış ad alanları içindeki iyi adlandırılmış sınıfların içindeki iyi adlandırılmış işlevler, okuyucularınızın kaybolmadığından emin olmanın en iyi yollarından biridir.

Cleancoders.com adresinde Clean Code, III. Bölüm'de bu konuda çok daha fazlası var

59
Uncle Bob.

Vay, bu cevapların çoğu hiç yardımcı olmuyor.

Kimliği tanımı olan hiçbir fonksiyon yazılmamalıdır . Yani, işlev adı yalnızca işlevin İngilizce olarak yazılmış kod bloğu ise, işlev olarak yazmayın.

conditionMet işlevinizi ve bu diğer işlevi, addOne (paslı JavaScript'im için affedin):

function conditionMet() { return x == condition; }

function addOne(x) { return x + 1; }

conditionMet uygun bir kavramsal tanımdır; addOne bir totoloji . conditionMet iyidir çünkü conditionMet 'nin sadece "koşul karşılandı" diyerek neyi gerektirdiğini bilmiyorsunuz, ancak İngilizce okursanız addOne' ın neden aptal olduğunu görebilirsiniz :

"For the condition to be met is for x to equal condition" <-- explanatory! meaningful! useful!

"To add one to x is to take x and add one." <-- wtf!

Hala kutsal olabilecek herhangi bir şeyin aşkı için lütfen totolojik işlevler yazmayın!

(Aynı nedenden dolayı, her kod satırı için yorum yazmayın !)

53
Rei Miyasaka

Bazı kodların niyetinin bir yorum ekleyerek geliştirilebileceğini düşünüyorsanız, bu yorumu eklemek yerine kodu kendi yöntemine çıkarın. Kod ne kadar küçük olursa olsun.

Örneğin, kodunuz aşağıdaki gibi olacaksa:

if x == 1 { ... } // is pixel on?

bunun gibi görünmesini sağlayın:

if pixelOn() { ... }

ile

function pixelOn() { return x == 1; }

Başka bir deyişle, yöntem uzunluğuyla değil, kendi kendini belgeleyen kodla ilgilidir.

14
Julio

Bence tam olarak bunu yapmak istiyorsun. Şu anda bu işlev sadece bir veya iki satır olabilir, ancak zamanla büyüyebilir. Ayrıca daha fazla işlev çağrısına sahip olmak, işlev çağrılarını okumanıza ve orada neler olduğunu anlamanıza olanak tanır. Bu, kodunuzu çok KURU (Kendinizi Tekrarlama) yapar ve bu da çok daha sürdürülebilirdir.

7
mpenrow

Gördüğüm diğer tüm yayınları kabul ediyorum. Bu iyi bir stil.

Optimize edici çağrıyı optimize edip kodu satır içinde yapabileceğinden, bu kadar küçük bir yöntemin ek yükü sıfır olabilir. Bunun gibi basit kod, optimize edicinin en iyi işini yapmasına izin verir.

Açıklık ve basitlik için kod yazılmalıdır. Bir yöntemi iki rolden biriyle sınırlamaya çalışıyorum: karar vermek; veya iş yapmak. Bu, bir satır yöntemi oluşturabilir. Bunu yaparken daha iyi, daha iyi kodumu bulmak.

Bunun gibi kodlar iyi bir kodlama uygulaması olan yüksek kohezyon ve düşük kuplaja sahip olma eğilimindedir.

EDIT: Yöntem adları hakkında bir not. Yöntemin nasıl yapmadığını belirten bir yöntem adı kullanın. Verb_noun (_modifier) ​​iyi bir adlandırma şemasıdır. Bu, Select_Customer_Using_NameIdx yerine Find_Customer_ByName gibi adlar verir. İkinci durum, yöntem değiştirildiğinde yanlış olmaya eğilimlidir. İlk durumda, tüm Müşteri veritabanı uygulamasını değiştirebilirsiniz.

5
BillThor

Bir kod satırını bir işleve yeniden ayarlamak aşırı gibi görünüyor. Ver loooooong/comples satırları veya ihraçlar gibi istisnai durumlar olabilir, ancak I know fonksiyon gelecekte büyüyemezse bunu yapmazdım.

ve ilk örneğiniz (koddaki diğer konulardan bahsedebilir veya konuşmayabilir) globallerin kullanımıyla ilgili ipuçlarını, daha fazla inceleyeceğim ve bu iki değişkeni parametre olarak yapacağım:

function conditionMet(x, condition){
   return x == condition;
}
....
conditionMet(1,(3-2));
conditionMet("abc","abc");

conditionMet example olabilir koşul uzun ve tekrarlıysa aşağıdaki gibi yararlı olabilir:

function conditionMet(x, someObject){
   return x == ((someObject.valA + someObject.valB - 15.4) / /*...whole bunch of other stuff...*/);
}

Bunu düşün:

Basit bir çarpışma algılama fonksiyonu:

bool collide(OBJ a, OBJ b)
{
    return(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) <= pow(a.radius + b.radius, 2));
}

Kodunuzda her zaman "basit" bir astar yazdıysanız, sonunda bir hata yapabilirsiniz. Ayrıca, bunu tekrar tekrar yazmak gerçekten haksızlık olur.

3
Mateen Ulhaq

Çok kısa olduklarını söyleyebilirim, ama bu benim öznel görüşüm.

Çünkü:

  • Yalnızca bir veya iki kez kullanılıyorsa, bir işlev oluşturmak için hiçbir neden yoktur. Defs atlama emmek. Özellikle inanılmaz hızlı VS ve C++ kodu ile.
  • Sınıfa genel bakış. Binlerce küçük fonksiyonunuz olduğunda, beni kızdırıyor. Sınıf tanımlarını görüntüleyebildiğimden ve ne yaptığını hızlı bir şekilde görebildiğim zaman zevk alıyorum, SetXToOne, SetYToVector3, MultiplyNumbers, + 100 setters/getters değil.
  • Çoğu projede, bu yardımcılar bir cevher iki yeniden düzenleme aşamasından sonra ölü ağırlık haline gelir ve daha sonra eski kod, genellikle ~% 25 + kurtulmak için "tüm arama" -> silmek.

Uzun işlevler kötüdür, ancak 3 satırdan kısa olan ve yalnızca 1 şey gerçekleştiren işlevler eşit derecede kötü IMHO'dur.

Bu yüzden, eğer sadece küçük bir fonksiyon yazmayı söyleyebilirim:

  • 3+ kod satırı
  • Junior Devs'in kaçırabileceği şeyler (bilmiyor)
  • Ek doğrulama yapar
  • En az 3x kullanılır veya kullanılır
  • Sık kullanılan arayüzü basitleştirir
  • Bir sonraki yeniden düzenleme sırasında ölü ağırlık olmayacak
  • Şablon uzmanlığı veya başka bir şey gibi bazı özel anlamları vardır
  • Bazı yalıtım işleri - const başvuruları, değiştirilebilir parametreleri etkiler, özel üye alımı

Bir sonraki geliştiricinin (kıdemli) tüm SetXToOne işlevlerini hatırlamaktan daha iyi şeyleri yapacağına bahse girerim. Bu yüzden her iki şekilde de ölü ağırlığa dönüşecekler.

2
Coder

Hayır, bu nadiren sorun oluyor. Birisi herhangi bir işlevin bir kod satırından daha uzun olmaması gerektiğini düşünüyorsa (sadece bu kadar basit olabilirse), bu bir problem ve bazı yönlerden tembel olur çünkü neyin uygun olduğunu düşünmüyorlar.

2
JeffO

Örnek no'yu sevmiyorum. 1, i genel adı nedeniyle.

conditionMet genel görünmüyor, bu yüzden belirli bir durumu mu temsil ediyor? Sevmek

isAdult () = { 
  age >= 18 
}

Bu iyi olur. Anlamsal bir fark olsa da,

isAtLeast18 () { age >= 18; } 

benim için iyi olmaz.

Belki sıklıkla kullanılır ve daha sonra değişime tabi olabilir:

getPreferredIcecream () { return List ("banana", "choclate", "Vanilla", "walnut") }

çok iyi. Birden fazla kez kullanarak, sadece tek bir yeri değiştirmeniz gerekir, eğer gerekirse - belki çırpılmış krema yarın mümkün olur.

isXYZ (Foo foo) { foo.x > 15 && foo.y < foo.x * 2 }

atomik değildir ve size güzel bir test fırsatı vermelidir.

Bir işlevi geçmeniz gerekiyorsa, elbette, istediğinizi geçin ve aksi halde aptal görünümlü işlevler yazın.

Ama genel olarak, çok kısa olan fonksiyonlardan çok kısa olan fonksiyonlardan çok daha fazla görüyorum.

Son Bir Kelime: Bazı işlevler yalnızca uygun görünür, çünkü çok ayrıntılı yazılmıştır:

function lessThan (a, b) {
  if (a < b) return true else return false; 
}

Görüyorsanız, bununla aynı olduğunu

return (a < b); 

ile bir problemin olmayacak

localLessThan = (a < b); 

onun yerine

localLessThan = lessThan (a, b); 
1
user unknown

Kod yok gibi bir kod yok!

Basit tutun ve işleri fazla zorlamayın.

Tembel değil, işinizi yapıyor!

0
RDL

Asla çok kısa bir problem değildir. Kısa fonksiyonların bazı nedenleri:

Yeniden kullanılabilirlik

Örneğin. ayarlanmış bir yöntem gibi bir fonksiyonunuz varsa, parametrelerin geçerli olduğundan emin olmak için bu işlevi kullanabilirsiniz. Bu kontrol değişkenin ayarlandığı her yerde yapılmalıdır.

İdame

İleride değişebileceğini düşündüğünüz bazı ifadeleri kullanabilirsiniz. Örneğin. şimdi bir sütunda bir sembol gösterirsiniz, ancak daha sonra başka bir şeye (hatta bir bip sesine) dönüşebilir.

tekdüzeliği

Örneğin; cephe modeli ve bir işlevin yaptığı tek şey, argümanları değiştirmeden işlevi tam olarak diğerine geçirmek.

0
Michel Keijzers

Bir kod bölümüne bir ad verdiğinizde, temel olarak bir ad vermek içindir. Bu, çeşitli nedenlerden herhangi biri olabilir, ancak önemli olan nokta, programınıza ekleyen bir anlamlı adı verebilmenizdir. "AddOneToCounter" gibi adlar hiçbir şey eklemez, ancak conditionMet() ekler.

Snippet'in çok kısa veya çok uzun olup olmadığını öğrenmek için bir kurala ihtiyacınız varsa, snippet için anlamlı bir ad bulmanın ne kadar zaman aldığını düşünün. Makul bir süre içinde yapamazsanız, snippet uygun bir boyut değildir.

0
user1249

Evet, kısa kod fonksiyonuna sahip olmak sorun değil. "Getters", "setters", "accesors" gibi yöntemler söz konusu olduğunda, daha önceki yanıtlarda belirtildiği gibi çok yaygındır.

Bazen, bu kısa "aksesuarlar" işlevleri sanaldır, çünkü alt sınıflarda geçersiz kılındığında işlevler daha fazla koda sahip olacaktır.

Eğer çok kısa, iyi değil, birçok fonksiyonda, küresel veya yöntemlerde fonksiyon istiyorsanız, genellikle doğrudan bir dönüş yerine bir "sonuç" değişkeni (Pascal tarzı) kullanın, bir hata ayıklayıcı kullanırken çok yararlı.

function int CalculateSomething() {
  int Result = -1;

   // more code, maybe, maybe not

  return Result;
}
0
umlcat

Hayır, ama çok kısa olabilir.

Unutmayın: Kod bir kez yazılır, ancak birçok kez okunur.

Derleyici için kod yazmayın. Kodunuzu korumak zorunda kalacak gelecekteki geliştiriciler için yazın.

0
Jim G.