Küçük tekrarlayan kod segmentleri için ne zaman bir işlev / yöntem yapılacağı konusunda iyi bir kod uygulaması nedir?


12

Kodları bir fonksiyona veya yönteme koymak mantıklı mı ve iyi bir kural nedir? Ben dört satır veya daha büyük bir başparmak kuralını kullanarak ve daha sonra iki kez daha görünür, o zaman bu kodu içeren basit bir işlev / yöntem yapmak. Daha iyi bir uygulama düşünebilir veya herhangi bir işaretçi sunabilir misiniz? Bu, dile özgü bir sorudan ziyade genel bir tasarım modeli sorusudur.

Yanıtlar:


29

İşlevleri kısmen kodu belgelemenin bir yolu olarak kullanıyorum. Anlamlı bir isimle bir fonksiyon çağırmak kodu anlamayı kolaylaştırır. Bazı durumlarda, tek satırlı bir işlev bile mantıklıdır.

Örneğin, "Temiz Kod" da, Robert C. Martin aşağıdaki örneği vermektedir: Hangisini görmeyi tercih edersiniz? Bu:

// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) &&
    (employee.age > 65))

Veya bu?

if (employee.isEligibleForFullBenefits())

Ona her zaman katılmıyorum, ama bu durumda kabul ediyorum. Kod, yalnızca yazdığınızda ve her ayrıntıyı bildiğinizde değil, başka bir kişinin kodundaki hataları düzeltmeniz gerektiğinde saat 9'da okunabilir olmalıdır. Uzun bir koşulda bakmak ve tüm çift negatifleri anlamaya çalışmak önerilmez. Üzerine sadece bir isim koyabilirseniz (sadece koşullar değil, yazdığınız her kod parçası), çok daha basit hale gelir.

Bir işleve bir şey koymaktan hiç pişman olmadım ve performans konusunda endişeleniyorsanız, önce profil yapın.


2
Bu basit uygulamayı takip etmek, sonunda uygulama kodunu nispeten yüksek bir seviyede yazmanıza izin verecektir. Küçük fonksiyonlar küçük sınıflara toplanır ve yakında fonksiyonel özellikleri neredeyse kelimesi kelimesine dönüştürürsünüz.
kevin cline

11
Bu örneği çok sevdim. Aniden bu yoruma artık ihtiyacınız yok. Bu genel bir kuraldır: Yorumunuz bir değişkene veya işlev adına dönüştürülebilirse, yapın!
Karoly Horvath

Burada omrib ile hemfikirim, genellikle kodu temizlemekle ilgili - onu diğer herhangi bir kuraldan daha okunabilir yapan şey. Sonunda bir şeyi tekrar kullanırsam, bir yönteme çıkaracağım. Ancak, IDE'm ve takımlarım genellikle bu konuda yardımcı oluyor, bu yüzden yapmak kolay ve hızlı.
Travis

+1 Bu tür kodlar, en azından JIT-ed olması gerekiyorsa daha da hızlı olabilir; yalnızca kullandığınız kadar ödersiniz.
Meslek

1
Niyeti Ortaya Çıkaran İsimler olarak da bilinir .
rwong

13

İşlev çağrılarının yalnızca tekrarlayan kod bölümlerinden kaçınmak için yapılması gerektiği konusunda yaygın bir yanlış anlama vardır. Temel kuralım, herhangi bir mantıksal iş biriminin, yalnızca tek bir yerde kullanıldığında bile bir işleve dönüştürülmesi gerektiğidir. Bu genellikle daha iyi bir okunabilirliğe yol açar ve işlev adlarının yorumların yerini aldığı ve ne yaptığınızı açıklayan ek yorumlar yazmanıza gerek kalmayan kendi kendini belgeleyen kod yazmanıza izin verir.


1
Yorum yazmaktan kaçınmak için programcıların hangi uzunluklara gideceğini görün?
Alger

1
@Alger olması gerektiği gibi
MatrixFrog

6

Den fazla kullanılan geçtiyse bir yerde ve

  • değişmesi muhtemeldir veya
  • doğru olmak zor

daha sonra bir işlev veya yöntem yapın. Deneyimlerime göre, uzun tekrarlanan kod parçaları doğal olarak bu kategorilerden birine girecektir (genellikle ilk olan, ancak kategoriler çok fazla örtüşür;). Tabii ki, arayüzde olması gereken her şey kendi başına bir işlev / yöntemdir.


3
Soru şudur: Doğru almak veya değişmesi muhtemel olmasa bile, sıkça tekrarlanan bir kod parçası için neden bir işlev yazmıyorsunuz? (Benim kuralım: tekrarlanan ve daha uzun bir işlev çağırıyorsa, bir işlev yapın)
Winston Ewert

Daha da ileri giderdim. Bir programcı olarak her türlü tekrarı ortadan kaldırmalısınız . Veritabanında olsun (normalleştirin), bazı manuel testler (birim testlerle değiştirin) veya dağıtım (otomatikleştirin).
Karoly Horvath

@ Winston: kullanılan dile bağlıdır. Her yapı doğal olarak bir işlev olarak yakalanamaz, işlev orijinal koddan daha fazla yer kaplayabilir (C'yi düşünün ve işaretçiyle geri dönün), işlev çağrıları ek yüke neden olabilir.
Fred Foo

@larsman, "(C'yi düşün ve işaretçi ile geri dön)" ile neye atıfta bulunduğunuzu merak ediyorum. Ama söylediğiniz şey başparmak kuralımla baş etmeye çalıştığım şey. İşlevin çağrılması daha kolay olmalıdır (yani, doğal olarak yakalama ve daha az yer kaplama), sonra işlevin içeriğini uygulama.
Winston Ewert

Bir kod parçası birden fazla değer hesaplıyorsa, diyelim ki float x, int yve double densitysonra bu hesaplamaları bir C işlevi olarak ayarlamak, üç değeri de elde etmek için bir yol tasarlamanız gerektiğinden, kodu tekrarlamaktan daha zor olabilir. Tekrarlanan hesaplamaların kendileri önemsizse, bazen bunları satır içinde bırakmak daha iyidir.
Fred Foo

4

Neredeyse her zaman, özellikle de her bir kopya aynı işlemi kavramsal bir bakış açısından temsil ediyorsa. Aynı şekilde, ancak farklı türlerde gerçekleştirilirse, genel bir uygulama yapın.

Düşünebilmemin tek nedeni bakımlardan biridir: bazen, ayrı bir şeyler arasında bir bağımlılık yaratmaktan kaçınmak, hatta bazı çoğaltma pahasına bile daha uygun olabilir.


Şimdilik uygulama benzerse, ancak yazım işlevine dikkat edin , ancak işlevsellik etkili bir şekilde farklıysa, ikisini birleştirmek, geri bölünmek için cehennem olarak can sıkıcı hale getirir. Özellikle IDE desteği zayıf olan dillerde (hey, C ++ 'da çalışıyorum ...)
Matthieu M.

Öte yandan, onları birbirinden ayırarak test etmek için aynı şeyi yapan iki fonksiyonunuz var, kodunuzun kullanılma şansının yarısı, aynı hatanın sürünebileceği iki yer var ve hata henüz tespit edilmedi. Hala C ++, zayıf IDE desteği olmasına rağmen ;-) çalışmak istiyorum
Nicola Musatti

1

"Şeklinde bir arama üstlenmeden " Bu çok yaygın süreci için sanayi "en iyi uygulamalar" için pek çok kaynağa götürecektir. Bir zamanlar meşhur olan " Once and Only Once" makalesi, bazılarının sorunuzun dile getirdiği endişeler için "en iyi uygulamalar" olarak gördüklerini açıklayan harika bir tarihsel referanstır. Ayrıca, daha genel bir kavram Kendinizi Tekrarlama (DRY) olarak bilinir . Sorunuzun cevaplar gerçekten derinlemesine kümesi için okumak Martin Fowler 'ın büyük klasik, yeniden düzenleme: Mevcut Kanunun Tasarımı iyileştirilmesi için en iyi bilinen tavsiye bazı kapsar üstlenmeden sezgisel olarak gerçekleştirmek için çalışıyoruz ne olduğu, !


0

Kod bir kereden fazla bir yerde tam olarak tekrarlanıyorsa ve tekrarlanan bölüm yakın gelecekte değişmeyecekse, bir fonksiyona ayırırım.


1
eğer değişecekse, onu yeniden düzenlemek için daha fazla neden. O zaman sadece bir kez değiştirmek zorunda
kalacaksınız

0

Bu, tekrarlanan kodun uyumunun doğasına bağlıdır. Kodun tekrarlanan bölümü belirli bir işlevi yerine getiriyorsa, kısmen DRY ilkesi nedeniyle, kısmen işlevin optimize edilmesi veya düzeltilmesi gerekiyorsa, sadece bir bölüm olduğu için bir yönteme dönüştürülmek için mükemmel bir adaydır. başa çıkmak için kod.

İlişkilendirme rastlantısalsa, kodu bir yönteme dönüştürmek yerine tekrarlamak daha iyidir. Bu snippet'in kullanımlarından birini karşılamak için kod dizilerinden birinin ortasına bir şey eklemeniz gerekiyorsa, bir yöntemdeyse, yaptığınız değişiklik o yöntemin diğer kullanımlarını etkileyebilir.

Kod uyumu kavramı hakkındaki Wikipedia makalesine bakın .


dernek rastlantısal görünüyorsa, iki sürecin ortak bir fikri paylaşması muhtemeldir ve muhtemelen iki sürecin gerçekten de aynı şeyin iki yönü olup olmadığını araştırmalısınız. Çoğu zaman, öyle değil.
Lie Ryan

0

Yapısal programlama anlamındaki fonksiyonlar ve bir sınıfın yöntemleri arasındaki farkı ayırt etmelisiniz.

Örneğinizde, gösterdiğiniz şey , bu şekilde bir satır içi kodlanmaması gereken bir yöntemdir .

bir sayı olup olmadığını görmek için bir dizeyi doğrulamanız gerekebilir, bu durumda bir işlev kullanırsınız ve önceki yanıtların çoğu uygulanır.

Bu ayrım özellikle büyük projelerde önemlidir.

Mümkün olduğunca, iş kurallarını (yöntemler) bilgisayar algoritmalarından (saf programlama işlevleri) ayırmaya çalışın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.