Yöntem parametresi olarak tanımlayıcıya karşı etki alanı nesnesi


10

Yöntem / işlev parametreleri olarak nesnelerin benzersiz kimliğe karşı kullanılmasına karşı veya bunlara karşı nesnel argümanlar var mı? (ve diğer nesnelerin üyeleri?). Özellikle statik olarak yazılan diller bağlamında (C # / Java / Scala)

Nesnenin Artıları:

  • Daha güvenli aramalar. Kimliklerde argümanların yanlış sıralanması riski vardır. Bu, yalnızca o sınıfın kimliğini depolayan her sınıf için bir 'mini' sınıf tutularak azaltılabilir.
  • Kalıcılıktan bir kez alın, tekrar almaya gerek yok
  • Kimlik ile, kimlik türü değişirse, int -> long deyin, o zaman hata olasılığına sahip tahtada değişiklik gerektirir .. (courtsey: https://softwareengineering.stackexchange.com/a/284734/145808 )

Kimlik kullanımının artıları:

  • Çoğu zaman gerçek nesneye gerek yoktur, sadece uniqueid olurdu, bu yüzden kimliğe sahip olmak onu kalıcı olmaktan kurtarır.

Bu tekniklerin bir karışımı, görebildiğim kadarıyla, hiçbirinin hem hem de artılarının eksileri olurdu.

Bunun somut olarak tanımlanmış bir sorun olduğu düşünüldüğünde, umarım objektif cevaplar vardır ve "sanırım" ya da "Seviyorum" türleri değil ... :-).

EDIT: Bir yorumcunun önerisi bağlamı- Tek kısıtlama statik olarak yazılmış dillerdir. Her ne kadar belirli kullanım senaryolarına dayalı cevaplar almak için mutlu olsa da, uygulama genel amaçlı bir uygulamadır.

EDIT: Biraz daha bağlam. Diyelim ki bir kitap yönetim sistemim var. Modelim:

Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}

Table- wishlist: { isbn: String, memberId: Int}
Table- borrows:  { id: Int, memberId: Int}  

Method: 
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int,  memberId: Int)

handleBorrowRequest( memberId: Int, book: Book ){ 
   //the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing. 
}

Neden tam üyeyi değil, sadece kimliği tutmak isteyeyim? Kitap hakkında bilgi aldığımda, kitabı kimin bağışladığını veya ödünç aldığını bilmem gerek. DonatedBy ve borrowedBy alanlarını doldurmak için tam bilgi almak bir aşırı iş.

Tabii ki, bunlar sadece benim düşüncelerim. Eminim bir şeyleri kaçırıyorum, bu yüzden lehte / aleyhte olan noktaların ne olduğunu bilmek istedim.


Sorunuzu biraz daha bağlamla düzenleyebilir misiniz? Senaryonun ne olduğu belli değil. Bir ORM sistemi (Hibernate gibi) tarafından yönetilen nesneler hakkında konuştuğunuzu ve "mini-class" ile tembel bir yükleme proxy nesnesi anlamına geldiğinizi tahmin edeceğim .
Darien


Buraya yorum olarak ekleme (tam özellikli bir cevaba genişletmek için yeterli bağlam elde edene kadar): Kodunuzdaki sabit kodlu kimlik değerlerini (büyük bir hayır-hayır) sürece , kimlik değerlerinizi yüklemeniz gerekir bir yerden değil mi? "Çoğu zaman" da oldukça belirsiz IMHO ...
hjk

@hjk Daha fazla bağlam ekledik, teşekkürler. Bir noktanız var - yine de bir yerden kimlik değerleri yüklemelisiniz. Ancak, DB 'dokunmak' değil DB kullanımı ve bant genişliği en aza indirmek hakkında değil. Bir kitap ödünç almak isteyen herkesin kimliğini alabilirim, ama aslında tüm ayrıntılarını almak gereksiz olurdu.
0fnt

Görünüşe göre bu birkaç şeye bağlı olacaktır: (1) kullanım senaryolarının gerçek nitelikleri (sütunlar) veya yalnızca bu kullanım senaryolarına bağlı olan kimliği gerektirip gerektirmediği; (2) kimlik-öznitelikleri sorgusunu zahmetsiz hale getirecek bazı önbellekleme veya performans artırıcı teknikler kullanıp kullanmadığınız ve kullanım durumlarınızın bu tür önbellek düzenlerini kıracak kadar ağır olup olmayacağı.
rwong

Yanıtlar:


8

Ortamınıza ve sorun içeriğinize bağlı olarak, veritabanına gitme ihtiyacı azaltılabilir ve sonuç olarak (IDO) yalnızca id'leri kullanma argümanı kaybolur.

Örneğin, PHP'nin Doctrine2 ORM'si EntityManager::getReferencesağlanan kimliği kullanarak bir varlığa tembel olarak yüklenmiş bir proxy üretir; Bunu başka kaç ORM yaptığını bilmiyorum, ama bahsettiğiniz bir "mini sınıf" nosyonuyla kabaca eşleşiyor. Çoğu niyet ve amaç için, bu tamamen hidratlanmış bir varlıktır, bu yüzden onu geçirebilir ve başka herhangi bir şekilde kullanabilirsiniz.

Bunun olmadığı tek durum, geçersiz bir kimlik verildiğinde ve bu durumda doğrulamak için yine de veritabanına gitmek istersiniz; artı, varlık elde etme maliyetini azaltmak için, çoğu ORM'nin (birinci ve ikinci seviye) önbellekleme işlevselliği vardır.

Veritabanına gitme ihtiyacını ve maliyetini azalttığımızda, büyük ölçüde profesyonelin varlığı bir parametre olarak kullanmalarına bırakılır:

  1. Tip güvenliği.
  2. Arayanın gerektirdiği daha az bilgi. 6 aylık bir geliştirici yanlışlıkla yanlış varlığın kimliğini geçemez.
  3. Daha düşük yeniden düzenleme maliyeti. Bir yöntemin varlıktan 2 parça bilgi gerektirecek şekilde değişmesi durumunda, arayan kişinin bunu başlatacak şekilde tamamen hidratlanmış varlığı aldığını varsayarak, arayanı sağlamak için değiştirmenin bir maliyeti yoktur.
  4. Yöntem başına daha az doğrulama gerekir. Birçok yöntem, verdikleri varlığın veritabanında bulunduğunu varsayabilir (ORM'den geldiğinden) ve bu nedenle artık kimliği doğrulamak zorunda değildir.
  5. (Potansiyel olarak) daha az veritabanı çağrısı. Kimlikleri 3 yönteme geçiriyorsanız ve her birinin bunu doğrulaması veya varlık hakkında daha fazla veri alması gerekiyorsa, bu, varlığı getiren 1 yöntem ve üzerinde çalışan 2 yöntemden 3 kat daha fazla veritabanı çağrısı demektir.

Elbette, kişinin sadece bir kimliği geçmek isteyebileceği durumlar vardır: örneğin sınırlı bir bağlam sınırını aşarken (alan güdümlü tasarımda konuşmak). Bir hesabı neyin oluşturduğuna dair farklı kavramlara sahip iki sınırlı bağlam (örneğin, finans ve müşteri ilişkileri) düşünürsek, içerik A'nın hesabını içerik B'ye aktaramayız. Bunun yerine, bir hesap kimliği (alan adının dilinde) karşıdan karşıya geçmek.


Önbellekleme, birden çok uygulama örneği çalışırken iyi ölçeklenmez. Kendi önbelleklemem var. Puan olsa mükemmel.
0fnt

Kimliklere karşı bir başka nokta da, kimliğin kullanılmasının aslında nesneyi de almak için, doğrulama dışında kalıcılık anlamına gelmesidir.
0fnt

3

Bu tür bir soru için, hangi çözümün programcı olarak niyetimi en iyi ilettiğine ve "Gelecek Greg" in işini en kolay hale getirdiğine inanıyorum.

Nesneyi bağımsız değişken olarak kullanmak, yöntem çağrısını 6 ay sonra doğru bir şekilde almayı kolaylaştırır ve bu uygulamanın cesur ayrıntılarını unuttum. "Bu kişinin istek listesi örneğindeki bu kitap" üzerine inşa etmek için, isInWishListyöntemin gerçekten sadece kitapların ve üyelerin tamsayılarını karşılaştırması gerektiğini varsayalım. Gerçekte, bu tek yöntemin işini yapmak için sadece iki veri parçasına ihtiyacı vardır. Şimdi bu yöntemden bir adım geri gidelim ve tüm yazılım sistemine bakalım. Çalışması için sadece bir kitap kimliği ve bir üye kimliği gerektirdiğinden şüpheliyim. Hatta aramadan önce tam kitabı ve üyeyi veritabanından çekiyor olacaksınız isInWishListçünkü muhtemelen bu tek yöntemi çağırmaktan daha fazlasını yapmanız gerekecek. Belki yaparsınız, ancak çoğu zaman daha fazlasını yapmanız gerekir.

Bununla birlikte, her iki nesneyi de veritabanından tam olarak getirip eşleyerek gerçekçi bir performans cezası almayacaksınız. Teorik olarak daha az veritabanı çağrısına ihtiyacınız olacak, ancak pratikte bunun doğru olmadığını göreceksiniz. Bu ID'leri sorgu dizesinde parametreler olarak sunucuya geri gönderirseniz, evet, sadece istek listesini veritabanından getirmeniz gerekir. Ancak bu, tüm uygulamanızın çok dar bir görünümüdür. Bir istek listesini kontrol etmenin yanı sıra başka işlemler gerçekleştirirken de senaryolar olacaktır - örneğin, bir istek listesine kitap ekleme. Yinelenen öğeler eklemek istemezsiniz.

Geçmektir anlamak için, yeni programcı ya da Future Self, en kolay gelen çözüm için gidin Bookve Membernesneleri. Sadece bir bulduktan sonra fiili performans sorunu sadece kimlikleri geçirerek ile gerçekten endişe kendinizi gerektiği.

Veya, Java gibi statik olarak yazılan dillerin aşırı yükleme yöntemi sunduğunu hatırlayabiliriz, böylece pastanızı alabilir ve yiyebilirsiniz:

public boolean isInWishList(int bookId, int memberId) {
    // ...
}

public boolean isInWishList(Book book, Member member) {
    return isInWishList(book.getId(), member.getId());
}

Bu sorunun asıl cevabı her iki yöntemi de yazmak, güçlü yazılan sürümden sadece tamsayı sürümünü çağırmak ve Bob amcanızdı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.