Neden fonksiyon isimlerindeki argümanların isimlerini kodlamak daha yaygın değil? [kapalı]


47

Gelen Temiz Kanunu yazar bir örnek verir

assertExpectedEqualsActual(expected, actual)

vs

assertEquals(expected, actual)

eski ile daha net olduğu iddia edildi, çünkü iddiaların nereye gittiğini hatırlama ihtiyacını ortadan kaldırıyor ve ondan gelen potansiyel suiistimali ortadan kaldırıyor. Yine de, herhangi bir kodda eski isimlendirme şemasının bir örneğini hiç görmedim ve ikincisini her zaman gördüm. Kodlayıcılar, yazarın iddia ettiği gibi, ikincisinden daha açıksa, neden eskisi benimsemez?


9
Bence bu tartışma için harika bir soru. Ancak nesnel cevapla cevaplanabilecek bir şey değil. Dolayısıyla bu soru kanaatine kapalı olarak kapatılabilir.
Mutlu

54
Birçok kişi ilk isimlendirme şemasına karşı çıkacaktır çünkü açıklığa yardımcı olacağı noktanın çok ötesinde aşırı derecede ayrıntılıdır . Özellikle assertEquals(), bu yöntem bir kod tabanında yüzlerce kez kullanıldığından, okurların kongreye bir kez aşina olmaları beklenebilir. Farklı çerçevelerin farklı kuralları vardır (örneğin (actual, expected) or an agnostic (sol, sağ) `), ama benim tecrübeme göre bu en ufak bir karışıklık kaynağı.
amon

5
Kazanç o kadar küçüktür ki, faydalarıyla karşılaştırıldığında, herhangi bir aklı başında biri muhtemelen uzaklaşacaktır. Daha akıcı bir yaklaşım istiyorsanız, denemek zorundasınız assert(a).toEqual(b)(IMO bile hala gereksizce ayrıntılı), bununla ilgili birkaç iddiayı zincirleyebilirsiniz.
Adriano Repetti

18
Gerçek ve beklenen değerler olduğunu nasıl biliyoruz? Kesinlikle olmalı assertExpectedValueEqualsActualValue? Ama bekleme, nasıl kullandığı olmadığını hatırlıyorum ==ya .equalsya Object.equals? Olmalı mı assertExpectedValueEqualsMethodReturnsTrueWithActualValueParameter?
user253751

6
Bu özel yöntem için, iki argümanın sırası önemli olmadığı için, bu adlandırma planının faydalarını desteklemeyi seçmenin kötü bir örnek gibi göründüğü göz önüne alındığında.
Steven Rands

Yanıtlar:


66

Çünkü yazmak için daha fazla ve okumak için daha fazla

En basit sebep, insanların daha az yazmaya çalışmaktan ve bu bilgiyi kodlamaktan daha çok yazı yazmak anlamına gelmesidir. Okurken argümanların sırasının ne olması gerektiğine aşina olsam bile, her zaman her şeyi okumak zorundayım. Argümanların sırasına aşina olmasanız bile ...

Birçok geliştirici IDE kullanıyor

IDE'ler genellikle belirli bir yönteme ait belgeleri gezdirerek veya bir klavye kısayoluyla görmek için bir mekanizma sağlar. Bu nedenle, parametrelerin adları her zaman el altındadır.

Argümanları kodlamak, çoğaltma ve eşleştirme sağlar

Parametrelerin adları zaten ne olduklarını belgelemelidir. Adları yöntem adına yazarak, bu bilgiyi yöntem imzasında da çoğaltırız. Ayrıca, yöntem adı ile parametreler arasında bir bağlantı yaratırız. Söyleyin expectedve actualkullanıcılarımız için kafa karıştırıcı. 'Dan' assertEquals(expected, actual)ye gitmek assertEquals(planned, real), işlevi kullanarak istemci kodunu değiştirmeyi gerektirmez. Going assertExpectedEqualsActual(expected, actual)için assertPlannedEqualsReal(planned, real)araçlarla API bir kırılma değişikliği. Ya da hızlı bir şekilde kafa karıştırıcı olan yöntem adını değiştirmiyoruz.

Belirsiz argümanlar yerine türler kullanın

Asıl mesele, aynı tür oldukları için kolayca değiştirilebilen belirsiz tartışmalara sahip olmamız. Bunun yerine tip düzenimizi ve derleyicimizi doğru sırayı uygulamak için kullanabiliriz:

class Expected<T> {
    private T value;
    Expected(T value) { this.value = value; }
    static Expected<T> is(T value) { return new Expected<T>(value); }
}

class Actual<T> {
    private T value;
    Actual(T value) { this.value = value; }
    static Actual<T> is(T value) { return new Actual<T>(value); }
}

static assertEquals(Expected<T> expected, Actual<T> actual) { /* ... */ }

// How it is used
assertEquals(Expected.is(10), Actual.is(x));

Bu daha sonra derleyici düzeyinde uygulanabilir ve bunları geri alamayacağınızı garanti eder. Farklı bir açıdan yaklaşırken, Hamcrest kütüphanesinin testler için yaptığı esas budur .


5
Eğer bir IDE kullanıyorsanız, balon yardımında parametre adlarına sahipsiniz; Eğer birini kullanmazsanız, fonksiyon ismini hatırlamak argümanları hatırlamakla eşdeğerdir, bu yüzden hiçbir şekilde hiçbir şey kazanılmaz.
Peter - Monica

29
assertExpectedEqualsActual"Yazmak ve okumak için daha fazla olduğu için " itiraz ederseniz , nasıl savunuculuk yapabilirsiniz assertEquals(Expected.is(10), Actual.is(x))?
ruakh

9
@ruakh karşılaştırılabilir değil. assertExpectedEqualsActualYine de programcının, argümanları doğru sırayla belirlemeye özen göstermesini gerektirir. assertEquals(Expected<T> expected, Actual<T> actual)İmza, tamamen farklı bir yaklaşım doğru kullanım, zorlamak için derleyici kullanır. Bu yaklaşımı kısalık için en uygun hale getirebilirsiniz, örneğin expect(10).equalsActual(x), ama sorun bu değildi…
Holger

6
Ayrıca, bu özel durumda (==), argümanların sırası aslında nihai değerle alakasızdır. Sipariş yalnızca bir yan etki için önemlidir (arızayı bildirme). Sipariş verirken, (marjinal olarak) daha mantıklı olabilir. Örneğin strcpy (dest, src).
Kristian H,

1
Özellikle çoğaltma ve birleştirme bölümüyle daha fazla anlaşamazsınız ... Bir işlev parametresinin adı her değiştiğinde, işlev adı da değişmek zorunda kalırsa, o işlevin tüm kullanımlarını izlemeniz gerekir. onları da değiştirin ...
Kodumuzu

20

Programlamada uzun süredir tartışılan bir soru soruyorsunuz. Ne kadar ayrıntılılık iyidir? Genel bir cevap olarak, geliştiriciler, argümanları adlandıran ekstra ayrıntıların buna değmeyeceğini bulmuşlardır.

Ayrıntı her zaman daha fazla netlik anlamına gelmez. Düşünmek

copyFromSourceStreamToDestinationStreamWithoutBlocking(fileStreamFromChoosePreferredOutputDialog, heuristicallyDecidedSourceFileHandle)

e karşı

copy(output, source)

Her ikisi de aynı hatayı içeriyor, ancak bu hatayı bulmayı gerçekten kolaylaştırdık mı? Genel bir kural olarak, hata ayıklamak için en kolay şey, böcek olan birkaç şey dışında her şeyin maksimum özdeyken olmasıdır ve bunlar size neyin yanlış gittiğini söyleyecek kadar ayrıntılıdır.

Ayrıntı vermenin uzun bir geçmişi var. Örneğin, bize sevilen isimler veren , genellikle popüler olmayan " Macar gösterimi " var lpszName. Bu, genel programcı popülasyonunda genel olarak yol kenarına düştü. Ancak, üye değişken adlarına ( mNameveya m_Nameveya gibi name_) karakter ekleme , bazı çevrelerde popülerlik göstermeye devam eder. Diğerleri bunu tamamen düşürdü. Kodlama stili belgeleri bir vektörü döndüren herhangi bir işlevin, işlev çağrısında vektörün çerçevesini belirtmesi gerektiğini gerektiren bir fizik simülasyonu kod tabanı üzerinde çalışıyorum getPositionECEF.

Apple tarafından popüler hale getirilen bazı diller ilginizi çekebilir. Objective-C, fonksiyon imzasının bir parçası olarak argüman adlarını içerir (Fonksiyon [atm withdrawFundsFrom: account usingPin: userProvidedPin], dokümantasyonda şu şekilde yazılır withdrawFundsFrom:usingPin:. Fonksiyonun adı budur). Swift, bağımsız değişken isimlerini işlev çağrıları ( greet(person: "Bob", day: "Tuesday")) içine koymanızı gerektiren benzer bir kararlar vermiştir .


13
Diğer tüm noktalar bir yana, yazılmış olsaydı okumak çok daha kolay olurdu . Ne kadar kolay olduğunu gördün mü ? Bunun nedeni, bu kabadayı kelimelerin arasına çıkan küçük değişiklikleri kaçırmamak için çok kolaydır ve sınır kelimelerinin nerede olduğunu bulmak daha uzun sürer. Kafa karıştırmak parçalamak. copyFromSourceStreamToDestinationStreamWithoutBlocking(fileStreamFromChoosePreferredOutputDialog, heuristicallyDecidedSourceFileHandle)copy_from_source_stream_to_destination_stream_without_blocking(file_stream_from_choose_preferred_output_dialog, heuristically_decided_source_file_handle)
tchrist

1
Obj-C sözdizimi withdrawFundsFrom: account usingPin: userProvidedPinaslında SmallTalk'tan ödünç alınmıştır.
joH1

14
Tristrist, kutsal savaşları içeren konularda haklı olduğunuzdan emin olun. Diğer taraf her zaman yanlış değildir.
Cort Ammon

3
@tchrist Addingunderscoresnakesthingseasiertoreadnotharderasyouseeargümanı değiştiriyor. Buradaki cevap, ihmal ettiğiniz büyük harf kullanımıdır. AddingCapitalizationMakesThingsEasyEnoughToReadAsYouCanSeeHere. İkincisi, 10'dan 9 kez, bir ad asla [verb][adjective][noun](her bloğun isteğe bağlı olduğu yerlerde) basit büyük harf kullanımı ile iyi okunabilen bir formattan öteye gitmemelidir :ReadSimpleName
Flater

5
tchrist - çalışmanızın bilimi ( ücretsiz tam metin bağlantısı ) sadece alt çizgi stilini kullanmak için eğitilmiş programcıların alt çizgi stilini okurken deve durumundan daha hızlı olduğunu gösterir. Veriler ayrıca, daha deneyimli konular için farkın daha küçük olduğunu göstermektedir (ve öğrencilerin çoğu da özellikle deneyimli olmadıklarını göstermektedir). Bu, deve vakasını kullanarak daha fazla zaman harcayan programcıların da aynı sonucu vereceği anlamına gelmiyor.
Jules

8

"Temiz Kod" yazarı meşru bir soruna işaret eder, ancak önerdiği çözüm oldukça kararsızdır. Belirsiz yöntem adlarını iyileştirmenin daha iyi yolları vardır.

O haklı assertEquals(xUnit tarzı birim test kütüphanelerinden) o beklenen argüman temizlemek yapmaz ve gerçek hangisi. Bu da beni ısırdı! Birçok birim test kütüphanesi bu sorunu not etmiştir ve aşağıdaki gibi alternatif sözdizimleri getirmiştir:

actual.Should().Be(expected);

Veya benzeri. Bu kesinlikle çok daha net assertEqualsama aynı zamanda çok daha iyi assertExpectedEqualsActual. Ve aynı zamanda çok daha fazla beste edilebilir.


1
Ben analım ve önerilen sırayı izliyorum ama bana göre sonuç fun(x)5 olmasını beklersem, sırayı tersine çevirirsek ne yanlış gidebilir assert(fun(x), 5)? - ? Seni nasıl ısırdı?
emory

3
@emory Ben jUnit (en azından) değerlerinden bir thourough hata mesajı oluşturur biliyoruz expectedve actualbunları ters doğru değil iletisine neden olabilir, bu yüzden. Ama yine de daha doğal göründüğünü kabul ediyorum :)
joH1

@ joH1 bana zayıf görünüyor. başarısız kod başarısız olur ve kodu geçen yapmanız olmadığını geçecek assert(expected, observed)ya assert(observed, expected). Daha iyi bir örnek gibi bir şey olurdu locateLatitudeLongitude- koordinatları ters çevirirseniz, ciddi şekilde karışıklığa neden olur.
emory

1
@emory Ünite testlerinde mantıklı hata mesajlarını umursamayan insanlar, bazı eski kod tabanlarında "Assert.IsTrue başarısız" ile uğraşmamın sebebi. Hangi hata ayıklamak için çok eğlenceli. Ancak evet, bu durumda sorun o kadar da önemli olmayabilir (argümanların sıralamasının genel olarak önemli olduğu yerlerde karşılaştırmalı karşılaştırmalar yapmamız dışında). Akıcı iddialar, gerçekten de bu sorunu önlemek ve aynı zamanda kodu daha etkileyici kılmak için harika bir yoldur (ve önyükleme için çok daha iyi bir hata mesajı sağlar).
Voo

@emory: Argümanı tersine çevirmek hata mesajlarını yanıltıcı hale getirir ve hata ayıklama sırasında sizi yanlış yola gönderir.
JacquesB

5

Scylla ve Charybdis arasındaki yolunuzu açıklığa yönlendirmeye, işe yaramaz fiil çekiciliğini (amaçsız başıboş da denir) ve aşırı kısalıkları (aynı zamanda kriptik terslik olarak da bilinir) önlemeye çalışıyorsunuz.

Bu nedenle, değerlendirmek istediğiniz arayüze, iki nesnenin eşit olduğu konusunda hata ayıklama iddiaları yapmanın bir yoluna bakmalıyız.

  1. Arity ve isim olarak düşünülebilecek başka bir fonksiyon var mı?
    Hayır, bu yüzden adın kendisi yeterince açık.
  2. Herhangi bir önemi var mı?
    Hayır, hadi görmezden gelelim. Bunu zaten yaptın mı? İyi.
  3. Argümanlarında simetrik mi?
    Neredeyse, hata durumunda, mesaj her bir argüman gösterimini kendi yerine koyar.

Öyleyse, bakalım bu küçük farkın herhangi bir önemi var mı ve var olan güçlü sözleşmelere dahil değil.

Argümanlar istemeden değiştirilirse, hedef kitle uygunsuz mu?
Hayır, geliştiriciler aynı zamanda yığın izini sürerler ve hatayı düzeltmek için kaynak kodunu yeniden incelemeliler.
Tam yığın izlemesi olmasa bile, iddia pozisyonu bu soruyu çözer. Ve eğer bu eksikse ve hangisinin olduğu mesajından belli değilse, olasılıkları en fazla iki katına çıkarır.

Argümanlar sırası sözleşmeyi takip ediyor mu?
Durumda gibi görünüyor. En iyi ihtimalle zayıf bir kongre gibi görünüyor.

Bu nedenle, fark oldukça önemsiz görünmektedir ve argüman sırası, onu fonksiyon-ismine kodlamak için herhangi bir çabanın negatif faydaya sahip olacağı konusunda yeterince güçlü bir sözleşmeyle kapsanmaktadır.


peki emir, jUnit ile ilgili olabilir ve bu değerlerden ( expectedve actualen azından Strings ile) belirli bir hata mesajı oluşturur
joH1

Sanırım bu kısmı kapattım ...
Deduplicator

Eğer söz ama göz önünde bulundurun: assertEquals("foo", "doo")hata mesajı verir ise ComparisonFailure: expected:<[f]oo> but was:<[d]oo>... değerlerini Değişim sesler daha o, mesajın anlamını evirmeliyiz karşıtı simetrik bana. Her neyse, bir dev'in hatayı çözmek için başka göstergeleri olduğunu söylediğiniz gibi, ancak IMHO’yu yanıltıcı olabilir ve biraz daha fazla hata ayıklama süresi alabilir.
joH1

Her iki kampın da (dest, src vs. src, dest), en azından AT&T ve Intel sözdizimi olduğu sürece bu konuda savunduğunu göz önünde bulundurarak, argüman siparişleri için bir "sözleşme" olduğu fikri komiktir. Ve birim testlerinde yardımcı olmayan hata mesajları, zorla değil eradike edilmesi gereken bir vebadır. Bu neredeyse "Assert.IsTrue başarısız oldu" ("hey, hata ayıklama için herhangi bir şekilde birim sınamasını yapmanız gerekiyor, bu yüzden tekrar çalıştırın ve orada bir kesme noktası koyun", "hey, yine de koduna bakmak zorundasınız Sadece sıranın doğru olup olmadığını kontrol edin ").
Voo

@Voo: Önemli olan, yanlış yapmak için "hasar" uygulamasının küçük olduğu (mantık buna bağlı değildir ve mesajlaşma programının önemli ölçüde bozulmadığıdır) ve IDE yazarken size parametrelerin ismini gösterecektir. ve yine de yazın.
Deduplicator

3

Genellikle herhangi bir mantıksal netlik katmaz.

"Add" i "AddFirstArgumentToSecondArgument" ile karşılaştırın.

Bir aşırı yüke ihtiyacınız varsa, örneğin, üç değer ekler. Daha anlamlı ne olurdu?

Üç argüman ile başka bir "Ekle"?

veya

"AddFirstAndSecondAndThirdArgument"?

Yöntemin adı mantıklı anlamını taşımalıdır. Ne yaptığını söylemeli. Mikro düzeyde, atılması gereken adımlar okuyucuyu kolaylaştırmaz. Argümanların isimleri gerekirse ek detaylar sağlayacaktır. Daha fazla ayrıntıya ihtiyacınız olursa, kod tam size göre olacaktır.


4
Adddeğişmeli bir işlem önerir. OP, emrin önemli olduğu durumlarla ilgilidir.
Rosie F,

Swift'de, örneğin add (5, to: x) işlevini çağırır ya da add () işlevini tanımlarsanız add (5, artı: 7, to: x) komutunu ya da add (5, artı: 7, giving: x) komutunu çağırırsınız. buna göre.
gnasher729

Üçüncü aşırı yük, "Toplam" olarak adlandırılmalıdır
StingyJack

@StringyJack Hmm .. Sum bir talimat değil, bir yöntem adı için daha az uygun hale getiren bir isimdir. Ancak bu şekilde hissediyorsanız ve bu konuda saf olmak istiyorsanız, iki argüman sürümüne de Sum adı verilmelidir. Bir Add yöntemine sahip olsaydınız, nesne örneğinin kendisine eklenmiş bir argüman olmalıdır (sayısal veya vektör bir tür olması gerekir). 2 veya daha fazla argüman çeşidi (onlara ne adlandıracaksanız) statik olacaktır. Sonra 3 veya daha fazla argüman sürümü gereksiz olurdu ve bir artı operatörü uyguladık: - |
Martin Maat

1
@Martin Neyi bekle? summükemmel cromulent olan fiil . "Özetlemek" ifadesinde özellikle yaygındır.
Voo

2

Diğer cevapların ima ettiği başka bir şey eklemek isterdim, ancak açıkça belirtildiğini sanmıyorum:

@puck, "İşlev adında ilk belirtilen argümanın gerçekten ilk parametre olduğuna dair hiçbir garanti yok.

@cbojar "belirsiz bağımsız değişkenler yerine türleri kullan" diyor

Mesele şu ki, programlama dilleri isimleri anlamıyor: sadece opak, atomik semboller gibi muamele görüyorlar. Bu nedenle, kod yorumlarında olduğu gibi, bir işlevin adlandırıldığı ile gerçekte nasıl çalıştığı arasında bir ilişki olması gerekmez.

assertExpectedEqualsActual(foo, bar)Bazı alternatiflerle karşılaştırın (bu sayfadan ve başka bir yerden), örneğin:

# Putting the arguments in a labelled structure
assertEquals({expected: foo, actual: bar})

# Using a keyword arguments language feature
assertEquals(expected=foo, actual=bar)

# Giving the arguments different types, forcing us to wrap them
assertEquals(Expected(foo), Actual(bar))

# Breaking the symmetry and attaching the code to one of the arguments
bar.Should().Be(foo)

Bunların hepsi , diline bakmak için opak olmayan bir şey veren ayrıntılı addan daha fazla yapıya sahiptir. İşlevin tanımı ve kullanımı da bu yapıya bağlıdır , bu nedenle uygulamanın ne yaptığı ile senkronize edilemez (bir isim veya yorum gibi).

Böyle bir sorunla karşılaştığımda veya gördüğümde, bilgisayarımı hayal kırıklığı içinde bağırmadan önce, makineyi suçlamanın 'adil' olup olmadığını sormak için biraz zaman ayırıyorum. Başka bir deyişle, istediğim şeyi istediğimden ayırt etmek için makineye yeterli bilgi verildi mi?

Böyle bir çağrı assertEqual(expected, actual)olduğu kadar his gibi markaların assertEqual(actual, expected)bize onları karıştırıyorum için, bu nedenle kolay ve makine önde azimle ve yanlış bir şey yapmak. Kullandığımız Eğer assertExpectedEqualsActualbunun yerine, yapmak olabilir bize az olası bir hata yapmak, ancak makineye hiçbir bilgi (o İngilizce anlayamıyorum ve ismin tercihi semantiğini etkilememelidir) verir.

Anahtar kelime argümanları, etiketli alanlar, farklı türler vb. Gibi "yapılandırılmış" yaklaşımları daha çok tercih edilen kılan şey, fazladan bilginin aynı zamanda makine tarafından okunabilmesidir , böylece makinenin yanlış kullanımları tespit etmesini sağlayabilir ve doğru şeyler yapmamıza yardımcı olabiliriz. assertEqualTek sorun yanlış mesajlar olurdu çünkü durum çok kötü değil. Çok farklı bir anlamı olan, String replace(String old, String new, String content)karışması kolay olan daha uğursuz bir örnek olabilir String replace(String content, String old, String new). Basit bir çare bir çift almak [old, new]olacaktır, bu da hataların derhal bir hatayı tetiklemesini sağlayacaktır (türler olmadan).

Türlerde bile kendimizi 'makineye ne istediğimizi söylemiyoruz' bulabileceğimizi unutmayın. Örneğin, "dizge yazmalı programlama" olarak adlandırılan anti-patern tüm verileri dizeler olarak ele alır, bu da argümanların karıştırılmasını (bu durumda olduğu gibi), bir adım atmayı unutmayı (örneğin kaçmayı), değişmeyenleri kırmayı (örneğin kaçmayı) kolaylaştırır. rakipsiz JSON) yapma, vb.

Bu aynı zamanda “boolean blindness” ile de ilgilidir, burada kodun bir bölümünde bir sürü boole (veya sayı, vb.) Hesaplıyoruz, ancak onları başka bir yerde kullanmaya çalışırken, aslında neyi temsil ettikleri, açık olup olmadığı açık değildir. Bunları karıştırdık, vb. Bunu, örneğin, açıklayıcı adları olan (örneğin LOGGING_DISABLEDyerine false) ve bunları karıştırırsak hata mesajına neden olan farklı numaralarla karşılaştırın .


1

çünkü argümanların nereye gittiğini hatırlama ihtiyacını ortadan kaldırır

Gerçekten mi? Fonksiyon isminde ilk belirtilen argümanın gerçekten ilk parametre olduğuna dair hala bir garanti yoktur. Bu yüzden daha iyi aramak (veya IDE'niz bunu yapsın) ve oldukça aptal bir isme güvenmek yerine, makul isimlerle kalın.

Kodu okursanız, parametreler olması gerektiği gibi adlandırıldığında ne olduğunu kolayca görmelisiniz. copy(source, destination)Anlaşılması, düşündüğümden daha kolay copyFromTheFirstLocationToTheSecondLocation(placeA, placeB).

Kodlayıcılar, yazarın iddia ettiği gibi, ikincisinden daha açıksa, neden eskisi benimsemez?

Çünkü farklı tarzlarda farklı bakış açıları var ve karşıtlığı belirten diğer makalelerin x yazarlarını bulabilirsiniz. Birinin bir yere yazdığı her şeyi takip etmeye çalışırken çıldırırsın ;-)


0

Parametre adlarını fonksiyon adlarına kodlamanın, fonksiyon yazmayı ve kullanmayı daha sezgisel hale getirdiğini kabul ediyorum.

copyFromSourceToDestination( // "...ahh yes, the source directory goes first"

Fonksiyon ve kabuk komutlarındaki argümanların sıralanmasını unutmak kolaydır ve birçok programcı bu nedenle IDE özelliklerine veya fonksiyon referanslarına güvenir. Adında açıklanan argümanlara sahip olmak, bu bağımlılığa karşı kesin bir çözüm olacaktır.

Bununla birlikte, bir kez yazıldığında, argümanların açıklaması, çoğu durumda adlandırılmış değişkenler kullanılacağından, ifadeyi okumak zorunda olan bir sonraki programcı için gereksiz hale gelir.

copy(sourceDir, destinationDir); // "...makes sense"

Bunun tersi çoğu programcının kazanacağını ve ben şahsen okumayı daha kolay buluyorum.

EDIT: @Blrfl'in işaret ettiği gibi, parametrelerin kodlanması her şeyden önce 'sezgisel' değildir, çünkü işlevin adını ilk başta hatırlamanız gerekir. Bu, fonksiyon referanslarına bakmak veya yine de parametre sipariş bilgilerini sağlayacak olan bir IDE'den yardım almayı gerektirir.


9
Bu yüzden şeytanın savunucusunu bir dakikalığına oynayabilirsem: İşlevin tam adını bildiğiniz zaman sezgiseldir. Bir kopyalama işlevi olduğunu biliyorsanız ve bunun copyFromSourceToDestinationya da olmadığını hatırlarsanız copyToDestinationFromSource, seçimleriniz onu deneme yanılma yoluyla buluyor veya referans materyalini okuyor. Kısmi isimleri tamamlayabilen IDE'ler, ikincisinin sadece otomatik bir versiyonudur.
Blrfl

@Blrfl Çağrının anlamı, copyFromSourceToDestinationeğer derlerseniz copyToDestinationFromSourcederleyicinizin hata bulacağını düşünüyorsunuz , ama çağrılırsa copy, bulamaz . Bir kopya-yordamın paraşütünü yanlış bir şekilde çevirmek kolaydır, çünkü strcpy, strcat vs. bir emsal teşkil eder. Ve kısa olanı okumak daha mı kolay? MergeLists (listA, listB, listC) listB ve listC'den listA oluşturur mu, yoksa listA ve listB'yi oku ve listC'yi yaz mı?
Rosie F,

4
@RosieF Argümanların ne anlama geldiği konusunda pozitif olmasaydım, kodu yazmadan önce belgeleri okurdum. Ayrıca, daha ayrıntılı fonksiyon isimleriyle bile, siparişin gerçekte ne olduğu hakkında yorum yapmak için hala yer vardır. Kurallara soğuk bakacak biri, işlevin adında olanın argümanların sırasını yansıttığına dair sözleşmeyi kurduğunuzu sezemez. Hâlâ vaktinden önce bilmek ya da belgeleri okumak zorunda kalacaklardı.
Blrfl

OTOH, hedefDir.copy (sourceDir); // "... daha mantıklı"
Kristian H

1
@KristianH Hangi yöne dir1.copy(dir2)çalışıyor? Fikrim yok. Ne hakkında dir1.copyTo(dir2)?
maaartinus
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.