Varsa bir şeyde bir şey yaratmak kötü kodlama uygulaması mıdır?


18

Yani getAccounthesabım varsa bir tanımlayıcı döndürecek bir yere sahip bir web hizmetim var, başka bir istisna atmak. İstemci, almanın yapıldığı bilgiyle bir istisna atılırsa her zaman bir hesap oluşturmak isteyecektir.

İçindeki tüm web hizmeti çağrılarını işleyecek müşteriler için kolaylık kitaplığı oluşturuyorum, böylece aramaları nasıl yapacaklarını bilmelerine gerek yok.

Merak ediyorum, getAccount(accountName)eğer varsa, hesabı alacak bir hesap oluşturacak olsaydım ve eğer o zaman onu oluşturup bilgiyi geri getirmezse, bu kötü bir şey mi? İstisnaları işlemek veya getOrCreateAccount gibi bir ad vermek için istemciye bırakmalı mıyım? Önemli mi?

Bir alma işleminde bir şey oluşturmak kötü bir uygulama mı?


9
En azından ben buna getOrCreateAccountbenzer bir ad verirdim.
Telastyn

4
Tembel başlatma bağlamında geçerli görünüyor. Ancak, bu deseni kütüphanenizde kullanmanız gerekip gerekmediğine bağlıdır.
Chris C

1
Fiilden acquirehoşlanıyorum acquireAccount. Karşılaştığım hiçbir büyük protokolde mevcut bir anlamı yok ve ona iyi uyan zorunlu bir halkası var. "Bunlardan birini benim için almak için ne gerekiyorsa yapın. İsteyin, inşa edin, sahte yapın, çalın, umrumda değil, sadece bir tane alın ya da denemekten ölün."
Dan Ross

2
"Müşteri her zaman bir hesap oluşturmak isteyecektir" - bu oldukça sıra dışı görünüyor. Kullanıcı kullanıcı adını yanlış yazdığı için hesabı alamıyorsam, kesinlikle yanlış adı olan bir hesap oluşturmak istemiyorum.
gnasher729

Javabean spec göre oracle.com/technetwork/articles/javaee/spec-136004.html getSomething() alıcılar içindir ve pastaneler setSomething()içindir. Imo daha entelektüel bir şey yapar şey yani başka bir şey çağrılmalıdır fetchSomething, obtainSomething, computeSomethingveya doSomethingElsevb
ccpizza

Yanıtlar:


31

Evet, önemli. Benim düşünceme göre, bir prosedürde yaratma gücüne sahip olduğu belgelenmemiş bir şey yaratmak genellikle kötü bir uygulamadır. Ya yordamı adlandırın getOrCreate...ya da ayrı bir create...yordam var ve sonra gerçekten isterseniz, getOrCreate...ilk denemeleri yapın get...ve başarısız olursa aramaları create...ve sonra aramaları yapın get....

Kitaplık kullanıcısı get..., get işlemi başarısız olursa yordamın oluşturulması için muhtemelen beklemeyecektir . Birdenbire, test çağrılarının get...bir ton veri oluşturduğunu fark ederlerse, muhtemelen oldukça şaşırırlar. Nasıl temizlerler? Ya eğer bir hata alacak kod düşünme yazarsanız get...başarısız olur ve onlar da ele almak istiyorum onların yol?


Teşekkürler, oluşturma aslında get... create... get...sadece ilk ikisini yapmak zorunda kalmazsınız olsun get çok dönecekti kimliği döndürür . Müşteriyle get, yaratmak istemeden basitçe bir çağrı yapma yeteneğine ihtiyaç duyup duymayacakları hakkında konuşacağım
Mike

6
@Mike: Hala ne olduğunu düşünüyorum create, sadece olanlar hakkında% 100 net olmak için.
SinirliWithFormsDesigner

Evet katılıyorum, getOrCreate çizgileri boyunca bir şey yapmayı planlıyordum çünkü orijinal düşüncem sadece yapmaktı, ama aynı zamanda arka planda bir şey yarattığının hemen net olmadığını fark ettim
Mike

1
Bu çok geç ama getOrCreatepopüler bir web çerçevesinde önceliğe sahip: docs.djangoproject.com/en/1.10/ref/models/querysets/…
tex

18

Hayır, 'kötü uygulama' değil. Siz ve diğer geliştiriciler, nasıl çalışmasını istediğinizi kabul ettiğiniz sürece, gayet iyi. Sonuçta, bir hesap döndürüyor olacaktı, bu da istediğin şey. Hesabın 'kaputun altında' oluşturulması, arayan ile ilgisizdir.


10
Herkese açık bir API olması tek istisnadır. Daha geniş bir topluluk, GET'in belirsiz ve nullipotent olduğu konusunda anlaşmıştı; diğer bir deyişle, her seferinde aynı eylem gerçekleştirilir ve sunucunun durumunu değiştirmeyen güvenli bir yöntemdir. Bu REST Wiki'sinde . Bunun yanı sıra, API sadece kendi küçük dünyanızda mevcutsa, grubunuz tarafından kabul edilen her şeyi yapın.
jmort253

9
Herkese açık bir API için bile , API'nin yapması gereken her şey bağlamında mantıklı olduğu sürece, bu fikre katılmıyorum . Tek bir numara işe yaradığında API'da birden çok giriş oluşturmanın pek bir anlamı yoktur.
GrandmasterB

Kayıt için bu tamamen dahili bir kütüphane ve ben sadece nasıl çalıştığını kullanarak takıma söyleme yeteneğine sahip
Mike

1
@ jmort253: İstemci tarafından görülebilecek hiçbir yan etkisi yoksa bir hizmet nullipotenttir . Sunucu istediği gibi yapabilir.
kevin cline

1
@kevincline, sanırım kredi kartımı borçlandırma açısından düşünürdüm. Sunucu kartımı bir GET isteğine göre ücretlendirir, ancak yine de her çalıştırdığımda bana "reddedildi" gibi bir sonuç verirse, bu GET'in ruhuna aykırı gibi geliyor. Bununla birlikte, görüşünü görüyorum. Sunucu, GET isteklerinin sayısını sayabilir ve 3 sorgudan sonra beni kilitleyebilir, böylece oranı sınırlandırır, ancak hesabımın ayrıntılarını değiştirmeden. Biri sunucu durumunun değiştirilmediğini söylediğinde bu önemli bir ayrım olduğunu düşünüyorum. Belki onun yerine "sunucudaki istemci durumu"
demeliyim

10

Her getAccount()zaman bir hesabı iade edebiliyorsa, arayanın bakış açısından, hesap vardır ve her zaman var olmuştur. Hiçbir getAccount()şey 'yaratmaya' gerek yok. Hesabın, varsayılan hesaptan farklı olana kadar hiçbir yerde saklanması gerekmez.


+1 Genel GetOrCreateolarak yanlış anlamsaldır, ancak fiziksel olarak var olup olmadığına bakılmaksızın "mantıklı" olabilecek bir nesne elde etmek iyidir. Örnek olarak, değişken öğelerin seyrek bir dizisi 1.841.533 elemanı için tahsis edilmiş bir depolama alanına sahip olmayabilir, ancak yine de bu elemanın yeni bir nesne oluşturarak, saklayarak ve bir referans döndürerek "alınmasına" izin verebilir.
supercat

4

3 yöntem oluşturmak en mantıklıdır:

getAccount -> Sadece hesabı alır.

createAccount -> Bir hesap oluşturur.

getAccountAndCreateIfNeeded -> Kendi adınızı seçin;)

Neden ayrılma: Almak ve oluşturmak için basit bir yönteminiz var. Bu her ikisi için de açık bir test edilebilir yöntemdir. GetAccount için hesabı bulmak bir istisna değildir . Bu yüzden sadece yanlış ya da bunun gibi bir şey döndürün, bekleniyor.

Sonra bu döndürülen değeri gruplandırılmış işlevinizde kullanabilirsiniz: getAccountAndCreateIfNeeded, şimdi de test edilebilir, her zaman bir hesap döndürmelidir. Ne istersen.

Tüm bu 3 yöntem açıktır, ne yaptıkları ve ne döndükleri açıktır. Artık ekibinizle anlaşma yapabilirsiniz, ancak bu tür istisnalar uzun vadede korkunçtur. Onları çok netleştirin ve hiçbir sorun yaşamayacaksınız.


Ayrıca, Temiz Kod'dan: "Yönteminiz adının ima ettiği şeyi yapamıyorsa, bir İstisna atın." 'GetOrCreateIfneeded' içinde başarısız bir GET atar ve daha sonra başarısız olsun için ne olursa olsun istisna türü için geri geliyor için Throw içinde 'createAccount' olan bir Try / Catch blok olurdu.
Graham

Dördüncü bir yöntem önerebilirim: getAccountIfExistsya bir hesap alır ya da yeni bir tane oluşturmadan var olmadığını gösterir. getAccountYöntem kendisi hesabın zaten var olduğunu varsayar ve bir istisna değilse atmak gerekir.
supercat

2

Duruma göre değişir.

Örneğin, tembel yükleme / örnekleme yapmak, veri yüklemesini ertelemek veya gerçekten gerekli olana kadar bir örnek oluşturmak için kullanabilirsiniz. Gereksinim duymayabileceğiniz kaynakları kaydettiği için bu normalde mantıklıdır (eğer sınıf / veri asla gerekli değilse o zaman asla yüklenmez).

Ancak, bu özel durumda, eğer olmasaydı yeni bir hesap oluşturacak bir getAccount yöntemine sahip olmanın iyi bir uygulama olmayacağını söyleyebilirim. Kullanıcı belirli bir hesabı tanımlamak için bazı kimlik bilgileri verdiyse ve bu hesap bulunamadıysa, bu, kullanıcının henüz bir müşteri olmadığı ve kendileri için oluşturulmuş bir hesabı olması gerektiği anlamına mı geliyor yoksa kimlik bilgilerinin yanlış yazıldığı anlamına mı geliyor? ve kullanıcıdan girmek istediklerini girip girmediğini doğrulaması istenmelidir?

Yeni bir hesap oluşturamazsa bir getAccount yönteminiz varsa, bu konuda bir seçeneğiniz yoktur. Hesap oluşturma ve hesabı ayrı yöntemlere bölme işlemlerini ayırırsanız, hesap alma girişimi başarısız olursa ne yapacağınıza karar verme konusunda çok daha fazla esnekliğe sahip olursunuz.

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.