İşlev argümanlarının sayısını en aza indirme teknikleri


13

Temiz Kod'da "bir işlev için ideal argüman sayısının sıfır olduğu" yazılır. Sebepleri açıklanır ve mantıklıdır. Sonra bu yöntemi çözmek için 4 veya daha fazla argüman ile yöntemleri yeniden düzenleme teknikleri.

Bir yol, argümanları yeni bir sınıfa çıkarmaktır, ancak bu kesinlikle sınıfların patlamasına neden olur mu? Ve bu sınıfların muhtemelen bazı adlandırma kurallarını ("Veri" veya "Bilgi" vb. İle biten) ihlal eden isimlerle mi sonuçlanacağı?

Başka bir teknik, birden fazla işlev tarafından kullanılan değişkenleri, bunları geçirmekten kaçınmak için özel bir üye değişken yapmaktır, ancak bu, değişkenin kapsamını genişletir, muhtemelen gerçekte ihtiyaç duymayan işlevlere açık olacak şekilde.

Sadece işlev argümanlarını en aza indirmenin yollarını aramak, bunun iyi bir fikir olmasının nedenlerini kabul etmek.


21
Tbh Temiz kodla hiç katılmıyorum. Bir işleve ilişkin bağımsız değişken sayısı sıfırsa, bu işlevin yan etkileri olduğunu ve muhtemelen bir yerlerde durumu değiştirdiğini gösterir. 4'den az argümanın iyi bir kural olabileceğini kabul etsem de - statik olan ve durumu değiştiren ve yan etkileri olan sıfır argümanlı statik olmayan bir fonksiyondan daha fazla yan etkisi olmayan 8 argümanlı bir fonksiyona sahip olmayı tercih ederim. .
wasatz

4
" Temiz Kod'da" bir işlev için ideal argüman sayısının sıfır olduğu "yazılmıştır. " Gerçekten mi? Bu çok yanlış! İdeal parametre sayısı birdir ve bir parametreden belirleyici olarak türetilen bir dönüş değeri vardır. Uygulamada, parametre sayısı önemli değildir; önemli olan, fonksiyonun mümkün olduğunda saf olması gerektiğidir (yani, dönüş değerini sadece yan etkisi olmayan parametrelerinden elde eder).
David Arno

2
Kitap daha sonra yan etkilerin arzu edilmediğini belirtmek için devam ediyor ...
Neil Barnwell


Yanıtlar:


16

Hatırlanması gereken en önemli şey, bunların kurallar değil, kurallar olduğudur.

Bir yöntemin basitçe bir argüman alması gereken durumlar vardır . +Örneğin sayılar için yöntemi düşünün . Veya addbir koleksiyon yöntemi.

Aslında, bir hatta iki numara eklemek için ne anlama geldiğini ℤ örn, bağlam bağlı olduğunu iddia edebilir 3 + 3 == 6, ama ℤ içinde | 5 3 + 3 == 2 , bu yüzden gerçekten toplama operatörü götüren bir bağlam nesne üzerinde bir yöntem olmalıdır iki a argümanlar yerine bir argüman alan sayılar üzerinde yöntem.

Benzer şekilde, iki nesneyi karşılaştırmak için bir yöntem, ya bir nesneyi diğerini bağımsız değişken olarak alan bir yöntem ya da bağlamın bir yöntemi, iki nesneyi bağımsız değişken olarak alarak olmalıdır, bu nedenle birden az argüman.

Bununla birlikte, bir yöntemin argüman sayısını azaltmak için yapılabilecek birkaç şey var:

  • Yöntemin kendisini küçültün : Belki, yöntemin bu kadar çok argümana ihtiyacı varsa, çok fazla şey yapıyor?
  • Eksik bir soyutlama : Eğer argümanlar birbiriyle yakından ilişkiliyse, belki de birbirlerine aittirler ve kaçırdığınız bir soyutlama var mı? (Kurallı ders kitabı örneği: iki koordinat yerine bir Pointnesne iletin veya kullanıcı adı ve e-posta iletmek yerine bir IdCardnesne iletin.)
  • Nesne durumu : Bağımsız değişkene birden çok yöntem gerekiyorsa, belki de nesne durumunun bir parçası olmalıdır. Bu yöntemlerden sadece bazıları için gerekliyken diğerleri için gerekli değilse, belki de nesne çok fazla şey yapıyor olabilir ve gerçekten iki nesne olmalıdır.

Bir yol, argümanları yeni bir sınıfa çıkarmaktır, ancak bu kesinlikle sınıfların patlamasına neden olur mu?

Etki alanı modelinizde çok farklı şeyler varsa, kodunuz çok farklı türde nesnelerle sonuçlanır. Bunda yanlış bir şey yok.

Ve bu sınıfların muhtemelen bazı adlandırma kurallarını ("Veri" veya "Bilgi" vb. İle biten) ihlal eden isimlerle mi sonuçlanacağı?

Doğru bir ad bulamazsanız, ya çok fazla argümanı bir araya getirdiniz ya da çok az argüman oluşturdunuz. Yani, ya sadece bir sınıfın parçasına sahipsiniz ya da birden fazla sınıfınız var.

Başka bir teknik, birden fazla işlev tarafından kullanılan değişkenleri, bunları geçirmekten kaçınmak için özel bir üye değişken yapmaktır, ancak bu, değişkenin kapsamını genişletir, muhtemelen gerçekte ihtiyaç duymayan işlevlere açık olacak şekilde.

Hepsi aynı argümanlar üzerinde çalışan bir yöntem grubunuz ve olmayan başka bir yöntem grubunuz varsa, belki de bunlar farklı sınıflara aittir.

"Belki" kelimesini ne sıklıkla kullandığımı not et. Bu yüzden bunlar kural değil kurallardır. Belki 4 parametreli yönteminiz gayet iyi!


7
@ BrunoSchäpper: Elbette: (1) " Yöntemin kendisini küçültün: Belki, yöntemin bu kadar çok argümana ihtiyacı varsa, çok fazla şey yapıyor? ". Parametre sayısı bunun zayıf bir testidir. İsteğe bağlı / boole parametreleri ve çok sayıda kod satırı, çok fazla şey yapan bir yöntemin güçlü göstergeleridir. Birçok param en iyi ihtimalle zayıftır. (2) " Nesne durumu: Bağımsız değişkene birden çok yöntem gerekiyorsa, belki nesne durumunun bir parçası olmalıdır ". Hayır, hayır ve üç, hayır. Nesne durumunu en aza indirin; işlev parametreleri değil. Mümkünse, nesne durumunu önlemek için parametrelerle tüm yöntemlere bir değer iletin.
David Arno

Eklemek için verdiğiniz örnek, düz bir şekilde yanlıştır. addDoğal sayılar için fonksiyonu ve addtamsayılar halkası için fonksiyon n iki farklı tipte iki farklı fonksiyonlar eylemlerdir mod. "Bağlam" ile ne demek istediğini anlamıyorum.
gardenhead

Teşekkürler @DavidArno. 1) hemfikir, kendi başına güçlü bir gösterge değil. Ama yine de iyi bir tane. Sık sık birkaç yöntem görüyorum, birkaç nesne çevrede geçti. Nesne durumu yok. Bu iyi, ama 2) daha iyi seçenek IMHO bu yöntemleri yeniden düzenliyor, örtük durumu tüm bu parametreleri açık argümanlar olarak alan yeni bir sınıfa taşıyor. Bir genel sıfır bağımsız değişken yöntemi ve birçok sıfırdan bir bağımsız değişken iç yöntemi ile sonuçlanır. Devlet kamuya açık, küresel değil, hatta uzun süre hayatta kalıyor, ancak kod çok daha temiz.
Bruno Schäpper

6

Sıfır bağımsız değişkenlerin yan etkiler anlamına gelmediğini unutmayın, çünkü nesneniz örtük bir bağımsız değişkendir. Örneğin, Scala'nın değişmez listesinin kaç tane sıfır-arity yöntemine sahip olduğuna bakın .

Yararlı bir teknik "mercek odaklama" tekniği olarak adlandırıyorum. Bir kamera merceğini odakladığınızda, çok fazla alırsanız gerçek odak noktasını görmek daha sonra doğru noktaya geri döndürmek daha kolaydır. Aynı şey yazılım yeniden düzenleme için de geçerlidir.

Özellikle dağıtılmış sürüm kontrolü kullanıyorsanız, yazılım değişikliklerini denemek kolaydır, nasıl göründüklerini beğenip beğenmediklerinizi görün ve eğer istemiyorsanız geri dönün, ancak bazı nedenlerden dolayı insanlar genellikle bunu yapmak konusunda isteksiz görünüyorlar.

Mevcut sorunuz bağlamında, bu, sıfır veya bir bağımsız değişken sürümünün yazılması, önce birkaç bölme işlevinin yazılması anlamına gelir, daha sonra okunabilirlik için hangi işlevlerin birleştirilmesi gerektiğini görmek nispeten kolaydır.

Yazarın, önemsiz test örneklerinizle başladığınız için başlangıçta düşük arititeli fonksiyonlar üretme eğiliminde olan test odaklı geliştirmenin büyük bir savunucusu olduğunu unutmayın.


1
"Lens odaklama" benzetmeniz gibi - Özellikle yeniden düzenleme yaparken, yakın çekim yerine geniş açılı lens kullanmak önemlidir. Ve parametrelerin # içine bakmak çok yakın
tofro

0

Basitçe (ve safça - ya da körü körüne söylemem gerekirse ) sadece işlevlere yönelik argümanların sayısını azaltmayı amaçlayan bir yaklaşım muhtemelen yanlıştır. Çok sayıda argümana sahip işlevlerde kesinlikle yanlış bir şey yoktur. Mantık tarafından isteniyorsa, iyi bir şeydir ... Uzun bir parametre listesi, okunabilirlik için düzgün bir şekilde biçimlendirilip yorumlandığı sürece beni hiç endişelendirmez.

Argümanlar tamamını veya bir alt kümesi bir benzersiz mantıksal varlık ait olup sık programı boyunca gruplar halinde etrafında geçirilen Bu durumda, bu belki biraz kaba grubuna bunları mantıklı - Tipik bir yapı ya da başka bir nesne. Tipik örnekler bir tür mesaj veya olay veri türü olabilir.

Bu yaklaşımı kolayca aşabilirsiniz - bu tür taşıma kaplarına paketleme ve ambalaj açmanın, okunabilirliği geliştirdiğinden daha fazla yük oluşturduğunu fark ettiğinizde, muhtemelen çok ileri gittiniz.

OTOH, büyük parametre listeleri, programınızın düzgün bir şekilde yapılandırılmamış olabileceğinin bir işareti olabilir - belki de bu kadar çok sayıda parametre gerektiren işlev sadece çok fazla şey yapmaya çalışır ve birkaç küçük işleve bölünmelidir. Buraya # parametre hakkında endişelenmektense başlamak istiyorum.


5
Tabii ki, argüman sayısını körü körüne azaltmak yanlış. Ama buna katılmıyorum "Çok sayıda argümana sahip işlevlerde kesinlikle yanlış bir şey yok." . Kanımca, çok sayıda argüman içeren bir fonksiyona çarptığınızda, tüm vakaların% 99,9'unda, kodun yapısını kasıtlı bir şekilde iyileştirmenin bir yolu vardır (bu da fonksiyonun argüman sayısını azaltır).
Doc Brown

@DocBrown Bu yüzden bu son paragraf ve orada başlamak için tavsiye var .... Ve başka bir: Muhtemelen bir MS Windows API karşı programlamaya çalışmadınız;)
tofro

"belki de bu kadar çok parametre gerektiren işlev sadece çok fazla şey yapmaya çalışıyor ve birkaç küçük işleve bölünmesi gerekiyor." Tamamen katılıyorum, ancak pratikte sadece birkaç küçük işlevi çağıran yığının üstünde daha yüksek bir işleve sahip değil misiniz? Daha sonra onları bir nesneye yeniden aktarabilirsiniz, ancak o nesnenin bir kralı olacaktır. Bir kurucu kullanabilirsiniz falan filan filan. Mesele, bu sonsuz bir gerilemedir - bir yerde, yazılımın işini yapması için gereken bir takım değerler vardır ve bir şekilde bu işlevlere ulaşmak zorundadırlar.
Neil Barnwell

1
@NeilBarnwell İdeal durumda (yeniden düzenleme yapmaya değer), 10 argüman gerektiren bir işlevi her biri 3-4 argüman gerektiren üçe bölebilirsiniz. Bu kadar ideal olmayan durumda, her biri 10 bağımsız değişkene ihtiyaç duyan üç fonksiyonla sonuçlanırsınız (daha sonra yalnız bırakmanız daha iyi). Daha üstteki yığın argümanınızla ilgili olarak: Kabul Ediyorum - Durum böyle olabilir, ancak zorunlu olarak değil - argümanlar bir yerden gelir ve bu geri alma yığının içinde de olabilir ve orada doğru yere konulması gerekir - Kilometre değişme eğilimindedir.
tofro

Yazılım mantığı hiçbir zaman dörtten fazla parametre gerektirmez. Sadece bir derleyici olabilir.
theDoctor

0

Sihirli bir yol yoktur: Doğru mimariyi keşfetmek için sorun etki alanında ustalaşmanız gerekir. Refactor için tek yol bu: sorunlu alanda uzmanlaşmak. Dörtten fazla parametre, mevcut mimarinizin hatalı ve yanlış olduğundan emin olabilirsiniz.

Tek istisna, sınırın teorik olarak 8, ancak muhtemelen sadece 5 olduğu derleyiciler (metaprogramlar) ve simülasyonlardır.

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.