Bir yöntemin parametre listesinde nesneler mi yoksa nesne tanımlayıcıları mı olmalı?


10

Ekiplerimiz aşağıdaki tartışmayı yapıyor:

Diyelim ki aşağıdaki iki yöntemimiz var:

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

tel üzerinden gönderilen sadece kimlikleri.

bir taraf ilk yöntemin doğru olduğunu söylüyor, çünkü sadece terminal ve kulüp kimliğine sahibiz ve başka bir şeyimiz olmadığı açık olmalı, bu benim yaklaşımım.

diğer taraf ise ikinci yöntemin doğru olduğunu söylüyor çünkü daha esnek.

Nesne parametresi fikrini biliyoruz, diğer taraf ayrıca object parametresinin nesnelere özellik olarak sahip olması gerektiğini düşünüyor.

Doğru yaklaşım hangisi?

Belki üçüncü bir yaklaşım daha iyidir?


Ne? ...........
James

1
Bağlam? İnternet servisi? WCF?
CodesInChaos

1
@James - Üzgünüm bu soruyu çok hızlı yazdım, anlaşılmayan ne olduğunu söyleyebilir misin?
Mithir

Yöntemler aslında BL yöntemleridir
Mithir

Yanıtlar:


10

Cevap bağlama bağlıdır.

İstemcinin tüm bu nesneleri zaten kullanması bekleniyorsa , nesne parametrelerini kullanırdım. Aksi takdirde, kodları olması gerekenden daha kıvrımlı görünecektir. (Örneğin club.getId(), örneğin çağrıları olacaktır .)

İstemcinin kimlikleri yalnızca kolayca kullanılabilecekse , ikinci yaklaşım daha iyidir, çünkü istemcinin gerçekten yalnızca kimliğe ihtiyacınız varsa tüm bu nesneleri bir araya getirmesini / yüklemesini istemeyebilirsiniz.

Bir seçenek her iki yöntemi de sağlamaktır , böylece müşteri hangisini kullanacağını seçebilir (bunun API'nizi karıştırmaması nedeniyle)

Genel olarak nesne parametreleri daha genişletilebilir, çünkü gelecekte işi yapmak için başka bir veri parçasına ihtiyacınız varsa, bu ekstra bilgiyi alan başka bir yöntem tanıtmanıza gerek yoktur.

Son olarak, yöntem imzalarınız yöntemin ne yaptığının (sizin durumunuzda tam olarak telin üzerinden geçenlerin) özelliklerine göre belirlenmemelidir. API soyut bir anlam ifade etmelidir, bu yüzden uygulama değişirse vidalanmazsınız.


3
+1 Sadece bir nokta daha ekleyeceğim: uzaktan ("tel üzerinden"?) Denilen yöntemler için, geçen nesneler kapsamlı bir nesne ağacının derinlemesine serileştirilmesini gerektirebilir. Kimlikler, uzaktan arama yükünün boyutuyla ilgili endişeleriniz olduğunda nesnelerin yerine kullanılabilir.
Ross Patterson

1
Bu durumda, bir dizi soyutlamaya bağlanmış gibi görünüyorsunuz, böylece Id'leri geçmek size daha fazla esneklik almayacak ve muhtemelen parametreleri tersine çevirme olasılığınızı artıracaktır. Soru, yöntemdeki kodun geçmekte olduğum soyutlamalarla ne kadar sıkı olduğunu? Örneğin, "validateCreditCard (dize kartı, dize cvi)" gibi bir yöntem, bir tür CreditCard nesnesiyle sıkıca birleştirilmekten kaçınmak için muhtemelen ilkellerle kalmalıdır.
ipaul

Ortada buluşur ve parametre listesinde bir arabirim kullanırdım. O zaman kulübünüz bir kulüp olabilir, ancak gelecekte bir sauna da olabilir.
Pieter B

13

İlk yaklaşım İlkel Saplantı'nın göstergesidir . İçeri ve dizeleri geçtiğiniz için, programcının hata yapması çok kolaydır (örn. Bir clubId'yi terminalId parametresine iletmek). Bu hataların bulunması zor olacaktır.

İkinci örnekte, bir terminal beklendiğinde bir kulübü geçmek imkansızdır - bu size derleme zamanı hatası verecektir.

Yine de, hala bakardım string invoice. Bir fatura gerçekten bir dize mi? Ne anlama amountgeliyor? Bu daha çok parasal bir değerdir.

Sorunuzda "tel üzerinden gönderilenler sadece kimliklerdir." Bu doğrudur, ancak bu gereksinimin alanınızı çamurlamasına izin vermeyin.

Bu yaklaşım lehine gördüğüm en iyi açıklama Object Calisthenics'in 3. kuralıydı :

Kendi başına bir int sadece bir skalerdir, bu yüzden bir anlamı yoktur. Bir yöntem int olarak parametre olarak alındığında, yöntem adının tüm amacı ifade etme işini yapması gerekir. Aynı yöntem parametre olarak bir Saat alırsa, neler olduğunu görmek çok daha kolaydır. Bunun gibi küçük nesneler, programları bir saat parametresi alan bir yönteme geçirmek mümkün olmadığından programları daha sürdürülebilir hale getirebilir. İlkel bir değişkenle derleyici, anlamsal olarak doğru programlar yazmanıza yardımcı olamaz. Bir nesne ile, hatta küçük bir nesne ile, hem derleyiciye hem de programcıya değerin ne olduğu ve neden kullanıldığına dair ek bilgi veriyorsunuz.


İkinci yaklaşım tercih ediliyor mu? sadece id özelliği dolu bir kulüp nesnesi olsa bile?
Mithir

Bu rastgele bir blog gibi görünüyor. Neyin tercih edildiğini söyleyecek kanıt yok. Tercih edilenin kimin umrunda? Sizin için neyin işe yaradığını yapın
James

@James Bu soruya kesin bir cevap yoktur, özellikle de OP bize çok fazla bağlam vermediğinden. Kategorik olarak bir yaklaşımın diğerine tercih edildiğini iddia eden herkes OP'ye bir kötülük yapıyor. O kadar siyah ve beyaz değil.
MattDavey

1
@James Ben sadece ilk yaklaşımın hataları bulmak zor tanıtmak için çok kolay olduğunu belirtti. İlkel türlerin kötü olduğunu söylemiyorum, ancak ilkel türlerin amacı anlamlı etki alanı türleri oluşturmaktır. Bunları bu bağlamın dışında kullanmak, ilkel takıntı kodu kokusunun tanımıdır.
MattDavey

5
@James: MattDavey'in söylediği şey köklü bir gerçektir. Yerel türlerin kötü olduğunu söylemiyor, bunu söylüyor: someMethod (int, int, int, string, ondalık), bir istemci tarafından anlamak ve kullanmaktan, someMethod'dan (Club, Terminal, Card, String) çok daha zor , ondalık)
c_maker

2

Buna doğru bir cevap yok. Her iki seçenek de iş için uygun olabilir. Neredeyse her şekilde, fatura argümanı kaşımda bir karık kaldırdı, kodu okurken ne olduğuna dair bir fikrim yok.

Bir kimlik gönderirseniz, her iki sistemin de temsil ettiği şeye sıkıca bağlanması gerekir. ClubID kulüpler tablosunda anahtardır. Daha da önemlisi, hem arayan hem de callee Kulüpler tablosunun ne olduğunu ve hangi veritabanının içinde olduğunu kabul etmelidir. Bu kısıtlamayı kabul etmek istemiyorsanız veya yapamıyorsanız, nesneyi bazı ortak açıklamaları kullanarak geçirirsiniz, yerli, serileştirilmiş, xml, ad = değer ne olursa olsun, bir ini dosyası :)

Tanımladığınız gibi "tel üzerinden" size mal olacak. Bundan kaçınmak, sadece tanımlayıcıyı göndererek başka bir yerde size maliyeti. Yani hangisi sizi en az acıtıyor, şimdi (veya daha sonra olabilir ...) iyinin kötüye göstergesidir.

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.