Saf POCO modellerine sahip olmanın faydası nedir?


16

Saf POCO modellerine sahip olmanın en büyük yararı nedir? Modellerin temiz ve basit olması gerektiğini anlıyorum, ancak alt nesnelerin bakımını model sınıfları içinde tutmaya eğilimliyim. Örneğin, a ClassAve ClassBaşağıdaki gibi tanımlanmışsa:

public class ClassA
{
    public string MyProp { get; set; }
    public IEnumerable<ClassB> Children { get; }

    public void AddChild(ClassB newChild) { /*... */ }
    public void RemoveChild(ClassB child) { /* ... */ }
}

public class ClassB
{
    public string SomeProp { get; set; }
} 

Ekle ve kaldır yöntemlerine sahip olmanın doğasında yanlış olan bir şey var mı? Bunun yerine sadece listeyi açığa çıkarmalı ve istemci kodunun, null değil ve başka bir sınıfa çoğaltılmaması gibi basit veri doğrulamalarının sorumluluğunu geçen her şeyi eklemesine izin vermeli miyim?

Herhangi bir yardım için teşekkür ederiz.


Nesnenin bir NullObject desen sürümüne boş bir ClassB argümanı çevirmek gibi bir değer eklemedikçe Ekle / Kaldır yöntemlerini kaldırabilirim:AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB())
Graham

ActiveRecord sınıflarının baş ağrısı ile herhangi bir zamanda istediğiniz gibi olabilecek veya olmayabilecek yüzlerce yöntemle başa çıkmışsanız, itirazın anlaşılmasının daha kolay olacağını düşünüyorum.
Casey

Bu tasarımdan kaçınmanın temel nedeni, .net tasarım yönergelerine aykırı olmasıdır. Tamamen keyfidir, ancak insanlar koleksiyonun mutasyon yöntemlerine sahip olmasını bekler.
Frank Hileman

@Casey Active Record kalıbını kullanmıyorum, add yöntemi sadece bazı küçük veri doğrulamaları yapıyor. Kaldırma yöntemi orada değildir çünkü koleksiyon gösterilmez, yalnızca dahili bir listeye ekler ve listeden kaldırırlar. Ben hala yerleşik Ekle / Kaldır yöntemleri kullanırken doğrulama yapmak için izin veren farklı bir koleksiyon türü kullanmak için değiştirdim.
Jesse

Yanıtlar:


44

İki sorunuz ilgisiz.

Saf POCO modellerine sahip olmanın faydası nedir?

Saf bir POCO, bazı girişimsel çerçeveye, sözleşmeye, [] bir şeye bağımlı değildir veya benzer şekilde bağımlı olan bir nesneye yakın bir şekilde bağlı değildir. Başka bir deyişle, dünya bir POCO etrafında tamamen değişebilir ve sadece umursamadan yaptıklarını yapmaya devam eder. Bir çerçeveyi güncelleyerek, yeni bir sisteme taşıyarak veya komik bir şekilde bakarak onu kıramazsınız. Sadece çalışmaya devam ediyor. Tek bağımlılıklar açıkça istediği şeylerdir.

POCO, POJO fikrinden başka bir şey değildir. J, bir C olarak değiştirildi, çünkü insanlar C # kullanıyorsa, adında Java olan bir kavramı açıkladığınızda insanlar size komik bakıyor. Fikir dile bağlı değildir. Basitçe Düz Eski Nesneler diyebilirlerdi. Ama kim POO kullanma konusunda övünmek istiyor?

Fowler'in kökenlerini açıklamasına izin vereceğim:

Terim Rebecca Parsons, Josh MacKenzie ve ben Eylül 2000'de bir konferansta konuşmaya hazırlanırken ortaya çıktı. Konuşmada, işletme mantığını Entity Beans kullanmak yerine normal java nesnelerine kodlamanın birçok faydasına işaret ediyorduk. İnsanların sistemlerinde normal nesneleri kullanmaya karşı niye bu kadar karşılandıklarını merak ettik ve bunun basit nesnelerin süslü bir adı olmadığı için olduğu sonucuna vardık. Bu yüzden onlara bir tane verdik ve çok güzel bir şekilde yakalandı.

martinfowler.com: POJO

Diğer sorunuza gelince:

Ekle ve kaldır yöntemlerine sahip olmanın doğasında yanlış olan bir şey var mı?

ADoğrudan bilmek hoşuma gitmiyor B. Ama bu bir DIP şey değil, bir POJO şey.


BBasitlik uğruna doğrudan bağımlılığım vardı , İdeal olarak bunların ikisi de arayüzleri uygulardı. Ama Ahala bir listesi var IInterfaceB. AddChildÇocukların arayüz referansları ile gevşek bir şekilde bağlanması durumunda yöntemde bir sorun var mı ?
Jesse

6
Basitlik uğruna bir sürü aptalca şey yapabilirim. Sevmediğim şey A'nın B'yi bilmesi değildir. Anlayabildiğim kadarıyla A bir koleksiyon. Bu yüzden A, <T> aracılığıyla B ile başa çıkmalı, böylece onun hakkında hiçbir şey bilmek zorunda kalmaz.
candied_orange

2
Kısaltmada herhangi bir dil belirtecinden kaçınmak için “düz eski veri nesnesi” için “PODO” da gördüm. PODO biraz aptalca geliyor (Tatooine'de duyacağınız bir epitet gibi geliyor bana), sanırım POJO veya POCO'dan daha çok, ama POO'dan çok daha az saçma.
KRyan

2
Ona POO demiş olsaydı Fowler'in sunumu ne kadar iyi olurdu?
Oliver

3

Ekle ve Kaldır ile Collection<T>özellikler uyguluyorsunuz . Kendinize, başka bir değişken sınıf IEnumerable<T>yerine neden kullandığınızı sorun. List<T>Görünüşe göre değil çünkü koleksiyonunuz salt okunur olmalıdır.

Düşünebilmemin tek nedeni, hangi erişim yöntemlerini yayınlamak istediğinizi kontrol etmek istemenizdir. Bu durumda, kendi toplama sınıfınızı oluşturmak, bir listeyi kapsüllemek, Ekle ve Kaldır ve uygulamak için seçtiğiniz yöntemleri uygulamak daha iyi olurdu IEnumerable<T>. Sonra IEnumerable<T>çocuk koleksiyonunuzun türü yerine bunu kullanın .

Ama bana öyle geliyor List<ClassB>ki muhtemelen sana iyi hizmet ederdi.


0

Ne AddChildekler ve ne RemoveChildkaldırır? Veritabanından (veya her türlü kalıcılık deposundan) ise, bir tür Aktif Kayıt elde edersiniz. Her zaman kötü bir şey olmak zorunda değildir, ancak kesinlikle @CandiedOrange'dan bahsedildiği gibi çerçeveler, sözleşmeler, bağımlılıklar vb.

Aynı zamanda, hepsi aynı uygulamadaysa ClassA'dan ClassB'ye (veya en azından InterfaceB) bağımlılıktan kaçınmanın anlamı nedir? Uygulamanızın modellediği gerçek dünya etki alanında işler birbirine bağlıdır. Gerçek dünya nesneleri yapmak olduğunu "aittir" onlara diğer nesnelerin koleksiyonları var. Kodunuzdaki bu ilişkileri temsil etmek tamamen uygundur.

Hatta biraz karmaşık hale gelmesinin tek nedeni, bir ClassB'nin ClassA ile nasıl ilişkilendirildiğini ve ClassA ile nasıl ilişkisiz hale geldiğini tam olarak yönetmeniz gerektiğine benziyor. Yani uygulamak için küçük bir davranışınız var. Sınıf içinde uygulayabilirsiniz (tamamen "yasal"; bkz. Https://stackoverflow.com/a/725365/44586 ) veya bu davranışı içeren bir tür ayrı sınıfa sahip olabilirsiniz. Bireysel koşullarınız için en anlamlı olanı yapın.

Her durumda, POJO / POCO gerçekten OOP, süslenmemiş ve numaralandırılmamış olması gerektiği gibi. OOP ilkelerini izleyin ve güvende olacaksınız.


Gerçekten AddChild sadece yineleme ve null olup olmadığını kontrol ediyor ve her ikisine de izin vermiyor. RemoveChild orada çünkü arka kapı eklemek önlemek için toplama IEnumerable olarak maruz. Ancak koleksiyondan yalnızca standart kaldırma işlemi gerçekleştirir.
Jesse

1
Açıkladığınız için teşekkürler. Evet, bu tam olarak bir POCO'da olması gereken davranış tipine benziyor ve arayanların istediği zaman değiştirmesi veya değiştirmesi için temel IEnumerable'unuzu açığa çıkarmadan kesinlikle daha iyi.
John M Gant

Aktif Kayıt sadece kötü bir model olduğunu düşünüyorum.
Casey

1
@Casey, benden bu konuda bir tartışma almayacaksın. Ama birileri de kullanmak isterse tartışmayacağım. Ana nokta, Jesse'nin kalıcılığı model tanımıyla bütünleştiren Aktif Kayıt gibi bir desen kullanmayı düşünmesi durumunda, CandiedOrange'ın vurguladığı tüm sorunlara sahip olacaktı ve buna değer bir şey için gerçekten bir POCO olarak nitelendirilmeyecekti. Ama yine de yaptığı şey bu değil.
John M Gant
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.