Martin Temiz Kodunda belirtildiği gibi çıktı argümanı nedir?


14

Robert C. Martin'in Temiz Kodu: Agile Yazılım İşçiliği El Kitabı'nın 45. sayfasında Martin, çıktı argümanlarından kaçınılması gerektiğini yazıyor. "Çıktı argümanının" anlamını ve neden bunlardan kaçınılması gerektiğini anlamakta zorlanıyorum.

Martin'in çıktı argümanı örneği appendFooter(s);işlevi çağırır public void appendFooter(StringBuffer report). Koddaki gelişimireport.appendFooter();

Belki de kod bağlamının eksikliğinden kaynaklanıyor, ancak çıktı argümanlarını kullanmanın nasıl kötü kodlama olarak değerlendirildiğini görmüyorum. Birisi kavramı açıklayabilir veya bunu anlamak için kod örneği verebilir mi?

Aşağıdaki fonksiyon yukarıdaki prensibe göre kirli kod örneği olarak düşünülebilir mi?

int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);

Yukarıdakiler Martin'in çıktı argümanlarını kullanmama ilkesinin ihlali durumunda, alan olarak dizi içeren bir nesneye ve diziyi sıralamak için çağrılabilecek bir işleve sahip olmak daha iyi olur mu?

ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();

Yanıtlar:


11

Bob Martin okunabilirlikten bahsediyor .

Örnekle ilgili sorun appendFooter, kod satırını appendFooter(s)bir programın herhangi bir yerinde bulursanız, bu çağrının sbir girdi olarak alınıp bir yere ekleyip eklemeyeceği veya o işlevin çıktısınıs almak için geçip geçmediği hemen belli olmaz . Emin olmak için, işlevin belgelerini kontrol etmeniz gerekir. Ancak, böyle bir çağrı bu sorunu önler: şimdi ne olduğu çok daha açık.report.appendFooter()

Ancak, Bob Martin "asla hiçbir zaman çıktı argümanlarını kullanma" demez, "genel olarak bundan kaçınmalısınız, çünkü kodunuzu biraz daha temiz tutmanıza yardımcı olacaktır" diyor. Yani bu körü körüne uyması gereken bir braindead kargo kült kuralı değildir.

Sortstandart diziler ve koleksiyonlar için yöntemler biraz farklıdır. sortYöntemin her standart dizi veri tipinin bir üye işlevine sahip olması, dil tasarımcısının bakış açısından birkaç dezavantaja sahip olacaktır, örneğin, Array.sortbunu Java çalışma zamanının dışında standart kitaplıkta tutmaya izin veren gibi bir yönteme sahip olacaktır . Ancak, bazen sıralanması gereken ayrı bir koleksiyon türü oluşturursanız, sortüye işlevi olarak eklemek , bunu ayrı bir sınıfa koymaktan daha iyi bir fikir olabilir.


2
sortArray(numberArray), tabii ki, numberArrayyerinde sıralar . Yoksa değiştirilmeden bir kopyasını oluşturur numberArray, kopyasını sıralar ve sıralanmış kopyayı döndürür numberArraymü?
8bittree

@ 8bittree: bu doğru, ama burada tartışma konusu değil - sort()bir konteyner yöntemi bir "çıktı argümanı" kullanmadan yerinde de çalışabilir. Bu nedenle sortArray(numberArray), yerinde bir yöntem "çıktı argüman formunu" haklı kılan hiçbir sebep olmadığı için.
Doc Brown

1
Demek istediğim sortArray(numberArray), ne yaptığının tamamen açık olmamasıydı . O takdirde Belli olabilir değil aynı tür o kabul ettiğini, o zaman yerde olmalıdır dönün. Ancak, dönüş türünü görmeden veya dönüş türü giriş türüyle eşleşiyorsa, tanımına bakmadan belirsizdir.
8bittree

1
@ 8bittree: Tamam, beni yakaladın, söz konusu ifadeyi cevabımdan kaldırdım. Ancak, açıkladığınız sorun bir üye işlevi kullanarak yok olmaz - "sıralama" üye işlevi bile bu şekilde davranabilir.
Doc Brown

11

İşlevden bir değer döndürmek için beklenmedik bir mekanizma kullanmak meselesidir, bu genellikle işlevde çok fazla şey yapmanın veya yanlış hizalanmış sorumluluklara sahip olmanın bir sonucudur. Şimdiye kadar, bir fonksiyonun sonucunu iletmenin en iyi yolu dönüş değerini kullanmaktır. Umarım bu apaçık ortadadır. Nesneye yönelik dillerde ikinci en iyi yöntem nesneyi değiştirmektir.

Bu iki seçenek arasında, bir işlevin sonucunu bildirmek için o kadar çok temiz ve bariz yol vardır ki, eğer argümanları tek yol olarak değiştirmek istediğinizi fark ederseniz, mimarinizde bir şeyler ters gitti. Mutasyona uğrayan kişinin öncelikle verilere sahip olması için sınıf sorumluluklarınızı yeniden düzenlemeniz gerekir.

Tek istisna çok genel algoritmalar içindir. Örneğin, bir sıralama algoritması, genel arabirimini kullanarak herhangi bir konteyner türüne genel olarak uygulanabiliyorsa, sıraladığı kaplardan haklı olarak ayrı olabilir. Tek vuruş appendFooterişlevinin bu mazereti yoktur.

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.