İsteğe bağlı parametreler yardımcı olur mu veya uygulama bakımının engellenmesi mi? [kapalı]


15

Başlıkta belirtildiği gibi , C # ' da kullanılanlar gibi isteğe bağlı parametreler yararlı mıdır veya uygulama bakımında bir engel midir ve kodun anlaşılmasını zorlaştırabileceklerinden kaçınılmalıdır mı?


3
Feragatname: yanlış ellerde herhangi bir dil özelliği kötüye kullanılabilir. Bir dil bunu akıllıca uygularsa ve bu dil özelliği varolan bir dil özelliğiyle sıkıcı bir şekilde örtüşmezse, o zaman gayet iyi, aslında oldukça yararlıdır. Python bazı düzgün param paketleme / açma ve diğer parametre "hileler" (Perl anlamda değil, iyi hileler) vardır.
Job

İsteğe bağlı parametreler kullanmadan C # 'da Excel ile arayüz oluşturan bir uygulama yazmayı deneyin. Bu, sorunuzu makul şüphelerin ötesinde cevaplamalıdır.
Dunk

Yanıtlar:


22

İsteğe bağlı parametreler, benim tecrübelerime göre, iyi bir şey oldu. Ben her zaman varsayılan değerleri almak ve ne denir biliyorum, çünkü ben onları kafa karıştırıcı (en azından gerçek işlev daha en azından kafa karıştırıcı) buldum.

Onlar için bir kullanım, zaten genel kullanımda olan bir işleve veya en azından genel arayüzde bir işleve başka bir parametre eklemem gerektiğidir. Onlar olmadan, başka bir argüman olan birini çağırmak için orijinal işlevi yeniden yapmak zorunda kalacaktım ve bir kereden fazla argüman eklemeyi bırakırsam bu gerçekten eski olabilir.


1
+1 Ve new Circle(size, color, filled, ellipseProportions)nerede sizeve colorgerekli ve geri kalanı varsayılan gibi bir argüman ekleyen aşırı yüklenmiş yöntemlerle değerlidir .
Michael K

15

Genel olarak, sık sık birçok / isteğe bağlı parametreye ihtiyacınız varsa, işlevleriniz çok fazla iş yapıyor ve parçalanması gerekiyor. Muhtemelen SRP'yi (Tek Sorumluluk İlkesi) ihlal ediyorsunuz.

Gruplandırılabilen parametreleri arayın, örneğin (x ve y, bir nokta haline gelir).

Bu isteğe bağlı parametre bayrakları varsayılan olarak mı? Bayraklar kullanıyorsanız, işlev bölünmelidir.

Bu, asla isteğe bağlı parametrelere sahip olmamanız gerektiği anlamına gelmez, ancak genel olarak, bir veya iki parametreden fazlası bir kod kokusu önerir.

Fonksiyonun, isteğe bağlı parametrelerin özelliklere ve yapıcı için gerekli parametreler kısmına değiştirilmesiyle, aslında bir sınıf olması gerektiğine dair bir ipucu da olabilir.


1
Dikkatli olmak için +1. Ne kadar iyi olursa olsun, herhangi bir özellik kötüye kullanılabilir.
Michael K

3
Bu, API'nizin kullanıcılarının en basit şeyi bile gerçekleştirmek için en az 6 sınıf ve 15 işlev kullanmak zorunda kaldıkları overengine edilmiş mantı kodu üretmek için harika bir tavsiyedir.
dsimcha

1
@dsimcha, bunu yazdıklarımdan nasıl alırsın? Vay. Lütfen açıkla? Bu, isteğe bağlı parametreleriniz olduğunda alacağınız "süper fonksiyon" a sahip olmak için aynı derecede kötü bir tasarım olacaktır. SOLID tasarım ilkeleri ve test edilebilir kod yazma hakkında bilgi edinin. Tercihen TDD kullanılarak. Sonra geri dönün ve bana işlevlerdeki parametreleri azaltmanın kötü bir şey olduğunu açıklamaya çalışın.
CaffGeek

1
Test edilebilir kod güzeldir, ancak aşırı ince taneli veya ayrıntılı olmayan ve bir işlevin uygun soyutlama olduğu durumlarda sınıfları yoksun bırakmayan temiz, kullanışlı bir API'dir. Sorumlulukların yüksek düzeyde soyutlanmış olarak tanımlandığı tek sorumluluk ilkesine inanıyorum. Sorumluluklar çok düşük bir seviyede tanımlanırsa, bireysel birimler etkileşimleri aşırı derecede karmaşık olacak şekilde aşırı basitleştirilir.
dsimcha

1
@dsimcha, noktayı kaçırıyorsun. Bireysel birimler bireysel birimler olarak kalmalı ve tek bir işlevde bir araya getirilmemelidir. Bu aynı zamanda herkesin erişebileceği işlevler olduğu anlamına gelmez. API'sınız, kodun ağ geçididir ve temiz ve özlü olmalıdır. Birkaç isteğe bağlı parametreye sahip bir işlev ne temiz ne de özlüdür. Bununla birlikte, tek bir fonksiyonun mantıksal parametrelerle aşırı yüklenmesi çok daha açıktır. Örneğin, birçok API'de iki parmın isteğe bağlı olduğu, ancak bir veya diğerinin gerekli olduğu işlevler vardır. Her ikisi de isteğe bağlı olarak işaretlendiğinde bunun ne anlamı var?
CaffGeek

4

İsteğe bağlı parametreler gayet iyi

Genellikle gerekçe şudur: a) yönteminiz için çok sayıda olası argümanınız olduğunu biliyorsunuz, ancak API'nizi kümeleme korkusu nedeniyle aşırı yüklemek istemiyorsunuz veya b) olası tüm argümanları bilmiyorsanız, ancak kullanıcıyı bir dizi sağlamaya zorlamak istemiyorum. Her durumda isteğe bağlı parametreler temiz ve zarif bir şekilde kurtarmaya gelir.

İşte bazı örnekler:

1. Aşırı yüklenmeyi önlemek istiyorsunuz ve bir dizi belirtmek istemiyorsunuz

C, Perl, Java vs.'den printf () ' a bir göz atın . İsteğe bağlı parametrelerin gücüne harika bir örnek.

Örneğin:

printf("I want %d %s %s",1,"chocolate","biccies");

printf("I want %d banana",1);

Aşırı yükleme yok, diziler yok, basit ve sezgisel (standart dize biçimi kodlarını kavradığınızda). Hatta bazı IDE'ler biçim dizenizin isteğe bağlı parametrelerinizle eşleşip eşleşmediğini bile size söyleyecektir.

2. Varsayılanların kullanımına izin vermek ve bunları yöntemin kullanıcısından gizli tutmak istiyorsunuz

SendEmail ( "test@example.org");

SendEmail yöntemi, çeşitli temel değerlerin eksik olduğunu algılar ve tanımlı varsayılanları (konu, gövde, cc, bcc vb.) Kullanarak doldurur. API temiz, ancak esnek tutulur.

Çok fazla parametre hakkında bir not

Ancak, diğerlerinin de belirttiği gibi, bir yönteme ilişkin çok fazla zorunlu parametreye sahip olmak, muhtemelen tasarımınızda bir sorun olduğunu gösterir. Bu, özellikle aynı tür paylaşımda bulunuyorlarsa doğrudur, çünkü çalışma zamanında garip sonuçlara yol açan kazara geliştirici tarafından değiştirilebilirler:

String myMethod(String x, String y, String z, String a, int b, String c, int d) {}

Oluşturmak Parametre Nesnesi yeniden düzenleme için ideal bir aday

String myMethod(ParameterObject po) {}

class ParameterObject {
  // Left as public for clarity
  public String x;
  public String y;
  ... etc

}

Bu da parametre nesnesi olarak sağlanan bir spesifikasyona sahip bir Fabrika modeline dayanan daha iyi bir tasarıma yol açabilir.


1
printf gibi dize biçimlendirme işlevleri, kuralın istisnasıdır , isteğe bağlı parametrelerin sınırsız bir listesini kullanırken , bağımsız değişkenin, nasıl uygulandığına rağmen, isteğe bağlı parametrelerden ziyade bir dizi olduğu iddia edilebilir.
CaffGeek

@Chad Cevabımı, isteğe bağlı parametreler ve bir kod kokusuna geçtiklerinde (yanıtınızda belirttiğiniz gibi) daha iyi ayırt etmek için ayarladım.
Gary Rowe

@Gary Rowe, çok fazla isteğe bağlı parametre çoğu durumda da kötüdür.
CaffGeek

@Chad Kabul ediyorum, ancak çoğu dil isteğe bağlı bağımsız değişkenlerin sayısında bir sınır belirlemenin bir yolunu sunmuyor, bu yüzden ya hep ya hiç yaklaşımı. Uygulamak için bunu yönteminize bırakmak zorundasınız ve açıkçası yönteminiz 500 değişkenle uğraşıyorsa, kesinlikle yeniden düzenlenmesi gerekecektir.
Gary Rowe

@Gary Rowe, "çoğu dil, isteğe bağlı bağımsız değişkenlerin sayısında bir sınır belirtmek için bir yol sağlamaz" ne demek? Çoğu dilde bunları bu şekilde işaretlersiniz veya işlevi çağırırken onlara değer sağlamazsınız, ancak işlev başlığında yine de parametreler tanımlanır. Bazı dillerde, tanımlanmış olanları doldurduktan sonra istediğiniz kadar parametre ekleyebilirsiniz, ancak bunun burada bahsettiğimiz isteğe bağlı parametreler olduğunu sanmıyorum. (dize biçimi istisnası dışında)
CaffGeek

2

C # varsayılan parametreleri ile sorunlardan biri (Ben voS DoSomething düşünüyorum (int x = 1)) sabitler olmasıdır. Bu, varsayılanı değiştirirseniz, bu yöntem çağrısının tüm tüketicilerini yeniden derlemeniz gerekeceği anlamına gelir. Bunu yapmak yeterince kolay olsa da, bunun tehlikeli olduğu durumlar vardır.


1

Kodunuzun ne yaptığına bağlıdır. Mantıklı varsayılanlar varsa, isteğe bağlı parametreler kullanmalısınız, ancak anlamlı varsayılanlar yoksa, isteğe bağlı parametreler eklemek kodunuzu daha karmaşık hale getirecektir. Birçok durumda isteğe bağlı parametreler, nil kontrollerini azaltmanın ve dallanma mantığını kesmenin düzgün bir yoludur. Javascript isteğe bağlı parametrelere sahip değildir, ancak onları taklit etmenin bir yolu vardır || (mantıksal veya) ve ben kullanıcı bazı değer vermez, o zaman ben kendi değerlerini || Bu da eğer if ifadelerinin bir demetini yazma zahmetinden kurtarır.


1

İsteğe bağlı parametreler, basit şeyleri basit ve karmaşık şeyleri aynı anda mümkün kılmak için harika bir yoldur. Çoğu kullanıcının isteyeceği açık bir makul varsayılan varsa, en azından hızlı ve kirli kullanım durumlarında, işlevinizi her aradıklarında manuel olarak belirtmek için kazan plakası yazmaları gerekmez. Öte yandan, insanların bunu değiştirmek istemek için iyi bir nedeni varsa, ortaya çıkması gerekir.

Bir sınıfı kullanmak IMHO korkunç bir çözümdür, çünkü bir sınıfın ne yaptığının tipik zihinsel modeliyle verimsiz, verimsiz ve tutarsızdır. İşlev, bir fiil için mükemmel bir soyutlamadır, yani bir şey yapmak ve geri dönmek. Sınıf, bir isim için doğru soyutlamadır, yani durumu olan ve çeşitli şekillerde manipüle edilebilen bir şey. Birincisi API kullanıcısının zihinsel modeli olmalı, o zaman bir sınıf yapmayın.


1

İsteğe bağlı argümanlarla ilgili sorun, insanların ilgili kodu yeni bir fonksiyona çıkarmak yerine, işleve gittikçe daha fazla (ve daha fazla) argüman koyma eğiliminde olmasıdır. Bu php aşırı alınır . Örneğin:

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
                      [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )

1

İsteğe bağlı parametreler temel olarak bir işlevi aşırı yüklemenin farklı bir yoludur. Yani bu temelde: "aşırı yük bir fonksiyon kötü mü?"


1

Başlangıçta python bu özelliği sevdim ve zaten kullanılan yöntemleri 'genişletmek' için kullanılır. Ve güzel ve kolay görünüyordu, ama yakında geri döndü; çünkü isteğe bağlı bir parametre eklediğimde bu, eski istemcinin dayandığı mevcut bir yöntemin davranışını ve mevcut birim sınama durumları tarafından yakalanmayan bir şekilde değiştiriyordu. Temel olarak bunu yapmak Açık Kapalı Prensibi'ni kırmaktır; kodu genişletme için açık ancak değişiklik için kapalı. Bu yüzden mevcut kodu değiştirmek için bu özelliği kullanmak iyi bir fikir olmadığına inanıyorum; ama en baştan kullanılırsa tamam


0

İsteğe bağlı parametreler kullanmaktan farklı imzalarla (yani parametrelerle) bir işlevi aşırı yüklemenin daha iyi olacağını düşünüyorum.


Neden? Eğer tüm yöntemler aynı temel işlevselliğe sahipse, varsayılan parametreler kullanarak bir grup aşırı yüklenmiş yöntemi bir yöntemle birleştirebilirseniz daha temiz olduğunu düşünüyorum
Amit Wadhwa

Bunu düşünebilirsiniz. Microsoft'un her şeyi doğru şekilde yaptığını düşünecek biri değilim, ancak doğru olsaydınız, .NET çerçevesini kullanırken asla aşırı yükleri göremezdim, sadece bir büyük işlev imzası - ol 'VB6'daki gibi.
HardCode
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.