Varlık yerine DTO'nun kullanımı nedir?


18

RCP uygulaması üzerinde çalışıyorum, bu uygulamada yeniyim.

Bahar çekirdekleri varlıkları kaydetmek / getirmek için iş mantığı yazmak için kullanılır.

Ancak, varlıkları doğrudan müşteriye göndermek yerine DTO'lara dönüştürüyor ve müşteriyi dolduruyoruz . Tasarruf ederken DTO'yu tekrar varlığa dönüştürüyor ve tasarruf ediyoruz.

Bu dönüşümlerin yararı nedir? Birisi açıklayabilir mi?


What's the benefit of these conversions?Kalıcılık veri modelinin tüketicilere sunulan veri modelinden (temsil) ayrıştırılması. Ayrışmanın faydaları SE'de geniş çapta tartışılmıştır. Bununla birlikte, DTO'ların altındaki amaç, istemcilerin sunucuya çağrı kaydetmesi için gerekli görülen bilgiler kadar tek bir yanıtta toplanmasıdır. İletişim istemci-sunucusunu daha pürüzsüz yapan nedir.
Laiv


Örneğin güzel. İstemci olduğunuzda (görüşler ...) değiştirmek acı vericidir, ancak en büyük sorun, sistemin zaten 3. tarafın entegrasyonlarına sahip olması, değiştirilmesi imkansızdır (sözleşme, ücretler ...). Sisteminizde üçüncü taraf entegrasyonu olacaksa, daima DTO kullanın.
Lucas Gonçalves

Yanıtlar:


45

Ne zaman bir geliştirici "bunu yapmanın anlamı nedir?" Bu amaçla size birkaç örnek göstereyim.


Tüm örnekler bu basit veri modeline dayanacaktır:

Bir Personişletmenin beş mülkü vardır:Id, FirstName, LastName, Age, CityId

Ve uygulamanın bu verileri çeşitli şekillerde (raporlar, formlar, pop-up'lar, ...) kullandığını varsayabilirsiniz.

Tüm uygulama zaten var. Bahsettiğim her şey mevcut kod tabanında bir değişiklik. Bunu hatırlamak önemlidir.


Örnek 1 - Temel veri yapısını değiştirme - DTO olmadan

Gereksinimler değişti. Kişinin yaşının, hükümet veri tabanından dinamik olarak alınması gerekir (diyelim ki ad ve soyadlarına göre).

AgeDeğeri artık yerel olarak depolamanız gerekmediğinden , Personvarlıktan kaldırılması gerekir . Burada varlığın veritabanı verilerini temsil ettiğini ve daha fazlası olmadığını anlamak önemlidir . Veritabanında değilse, varlıkta değildir.
Yaşı hükümetin web hizmetinden aldığınızda, bu farklı bir nesnede (veya int) depolanır.

Ancak ön ucunuz hala bir yaş gösteriyor. Tüm görünümler, Person.Ageartık mevcut olmayan mülkü kullanacak şekilde ayarlandı . Bir sorun kendiliğinden ortaya çıkar: Bir kişiye ilişkin tüm görünümlerin Agedüzeltilmesi gerekir .


Örnek 2 - Temel veri yapısını değiştirme - DTO ile

Eski sistemde, orada da PersonDTOaynı beş özelliklere sahip varlık: Id, FirstName, LastName, Age, CityId. A alındıktan sonra Person, hizmet katmanı a PersonDTOöğesine dönüştürür ve sonra döndürür.

Ama şimdi, gereksinimler değişti. Kişinin yaşının, hükümet veri tabanından dinamik olarak alınması gerekir (diyelim ki ad ve soyadlarına göre).

AgeDeğeri artık yerel olarak depolamanız gerekmediğinden , Personvarlıktan kaldırılması gerekir . Burada varlığın veritabanı verilerini temsil ettiğini ve daha fazlası olmadığını anlamak önemlidir . Veritabanında değilse, varlıkta değildir.

Eğer bir aracı var Ancak, PersonDTObu bu sınıf olduğunu görmek önemlidir tutmakAge özelliği. Hizmet katmanı getirilecek Person, a dönüştürülecek PersonDTO, daha sonra kişinin yaşını hükümetin web hizmetinden alacak, bu değeri depolayacak PersonDTO.Ageve o nesneyi iletecektir.

Burada önemli olan, servis katmanını kullanan herkesin eski ve yeni sistem arasında bir fark görmemesidir . Buna ön ucunuz da dahildir. Eski sistemde tam bir PersonDTOnesne aldı . Ve yeni sistemde hala tam bir PersonDTOnesne alıyor. Görünümlerin güncellenmesi gerekmez .

Endişelerin cümle ayrılmasını kullandığımızda kastettiğimiz budur : İki farklı endişe vardır (verileri veritabanında depolamak, verileri ön uca sunmak) ve her biri farklı bir veri türüne ihtiyaç duyarlar. Bu iki veri türü şu anda aynı verileri içeriyor olsa bile, bu gelecekte değişebilir.
Verilen örnekte, Ageiki veri türü arasında bir fark vardır: Person(veritabanı varlığı) bir Age, ancak PersonDTO(ön uç veri türü) buna ihtiyaç duymaz.
Endişeleri (= ayrı veri türleri oluşturmak) başından ayırarak, kod tabanı veri modelinde yapılan değişikliklere çok daha dayanıklıdır.

Veritabanına yeni bir sütun eklendiğinde, bir DTO nesnesine sahip olmanın, özelliği hem varlık hem de DTO'ya ekleyerek çift çalışma yapmanız gerektiği anlamına gelebilir. Bu teknik olarak doğrudur. Bir yerine iki sınıfı korumak için biraz fazla çaba gerektirir.

Ancak, gerekli çabayı karşılaştırmanız gerekir. Bir veya daha fazla yeni sütun eklendiğinde, birkaç özelliğin kopyalanması / yapıştırılması bu kadar uzun sürmez. Veri modeli yapısal olarak değiştiğinde, muhtemelen sadece çalışma zamanında (ve derleme zamanında değil) hatalara neden olacak şekilde ön ucu değiştirmek zorunda kaldığında, daha fazla çaba harcar ve geliştiricilerin hata aramalarını gerektirir.


Size daha fazla örnek verebilirim, ancak prensip her zaman aynı olacaktır.

Özetlemek

  • Ayrı sorumlulukların (endişelerin) birbirinden ayrı çalışması gerekir. Veri sınıfları gibi kaynakları paylaşmamalıdır (ör. Person)
  • Bir varlığın ve DTO'nun aynı özelliklere sahip olması, onları aynı varlıkla birleştirmeniz gerektiği anlamına gelmez. Köşeleri kesmeyin.
    • Daha açık bir örnek olarak, veritabanımızın ülkeleri, şarkıları ve insanları içerdiğini varsayalım. Tüm bu varlıkların bir Name. Ancak hepsinin bir Namemülkü olması, onları ortak bir EntityWithNametemel sınıftan miras almamız gerektiği anlamına gelmez . Farklı Nameözelliklerin anlamlı bir ilişkisi yoktur.
    • Özelliklerden biri değiştiğinde (örneğin, bir şarkının Nameadı değiştirilirse Titleveya bir kişi a FirstNameve alırsa LastName), ilk etapta bile ihtiyaç duymadığınız mirasın geri alınması için daha fazla çaba harcamak zorunda kalacaksınız .
    • Her ne kadar açık olmasa da, bir varlığınız olduğunda DTO'ya ihtiyacınız olmadığı iddiası aynıdır. Şu an bakıyorsunuz , ancak gelecekteki değişikliklere hazırlıklı değilsiniz. EĞER varlık ve DTO tam olarak aynıdır ve EĞER veri modeline herhangi bir değişiklik olmayacak garanti edemez; DTO'yu atlayabileceğiniz konusunda haklısınız. Ama mesele şu ki, veri modelinin asla değişmeyeceğini asla garanti edemezsiniz.
  • İyi uygulama her zaman derhal ödeme yapmaz. Eski bir uygulamayı yeniden ziyaret etmeniz gerektiğinde gelecekte ödemeye başlayabilir.
  • Mevcut kod tabanlarının ana katili, kod kalitesinin düşmesine izin vermek ve sürdürülemez olan spagetti kodunun gereksiz bir karmaşasına dönüşene kadar kod tabanının korunmasını sürekli olarak zorlaştırıyor.
  • Endişelerin en baştan ayrılmasını sağlamak gibi iyi uygulama, kod tabanının mümkün olduğu kadar uzun süre korunabilmesi için kaygan kötü bakım eğiminden kaçınmayı amaçlamaktadır.

Endişeleri birbirinden ayırmak için genel bir kural olarak, bunu şu şekilde düşünün:

Her endişenin (kullanıcı arayüzü, veritabanı, mantık) farklı bir konumdaki farklı bir kişi tarafından ele alındığını varsayalım. Yalnızca e-posta ile iletişim kurabilirler.

İyi ayrılmış bir kod tabanında, belirli bir endişede yapılacak bir değişikliğin yalnızca bir kişi tarafından ele alınması gerekir:

  • Kullanıcı arayüzünün değiştirilmesi yalnızca UI geliştiricisini içerir.
  • Veri depolama yönteminin değiştirilmesi yalnızca veritabanı dev.
  • İş mantığının değiştirilmesi yalnızca iş geliştiriciyi içerir.

Bu geliştiricilerin tümü aynı Personkuruluşu kullanıyorsa ve kuruluşta küçük bir değişiklik yapılmışsa, herkesin sürece dahil olması gerekir.

Ancak, her katman için ayrı veri sınıfları kullanarak, bu sorun yaygın değildir:

  • Veritabanı geliştiricisi geçerli bir PersonDTOnesneyi döndürebildiği sürece , işletme ve kullanıcı arabirimi, verilerin saklanma / alınma şeklini değiştirmesini umursamaz.
  • İşletme geliştiricisi verileri veritabanında sakladığı ve gerekli verileri ön uca sağladığı sürece, veritabanı ve UI geliştiricileri, iş kurallarını yeniden düzenlemeye karar verip vermeyeceğini umursamıyorlar.
  • Kullanıcı arayüzü `PersonViewModel etrafında tasarlanabildiği sürece, kullanıcı arayüzü kullanıcı arayüzü istedikleri gibi oluşturabilir. Veritabanı ve iş geliştiricileri nasıl yapıldığını umursamıyor, çünkü onları etkilemiyor.

Buradaki anahtar ifade, onları etkilememesi nedeniyle . Endişelerin iyi bir şekilde ayrıştırılması, diğer tarafları etkilemeyi (ve dolayısıyla dahil etmek zorunda kalmayı) en aza indirmeyi amaçlamaktadır.

Tabii ki, bazı büyük değişiklikler birden fazla kişiyi dahil etmekten kaçınamaz, örneğin veritabanına tamamen yeni bir varlık eklendiğinde. Ancak bir uygulamanın ömrü boyunca yapmanız gereken küçük değişikliklerin miktarını hafife almayın. Büyük değişiklikler sayısal bir azınlıktır.


Kapsamlı cevap, teşekkürler. Sorularım var; Cevabınız varsa teşekkür edin: 1 - Yanılıyorsam beni düzeltin. İş Nesnesi veya Görünüm Nesnesi , Sunum Katmanı ve İş Katmanı arasında veri aktarımı içindir ve Varlık Nesnesi , İş Katmanı ve Veri Erişim Katmanı arasında veri aktarımı içindir . ve DTO aptal bir BO olarak kullanılabilir. 2 - İki görüşün bir şirketin farklı bilgilerine ihtiyacı olduğunu varsayalım, o zaman iki farklı şirketDTO'una ihtiyacımız var mı?
Arash

1
@Arash (1) "DTO" iki katman arasında değiş tokuş yapmak için kullanılan herhangi bir veri sınıfı için bir tümünü yakalama tanımıdır. Bir iş nesnesi ve bir görünüm nesnesi her iki DTO'dur. (2) Bu çok fazla şeye bağlıdır. Gereksinim duyduğunuz her alan koleksiyonu için yeni bir dto oluşturmak hantal bir görevdir. Sadece tam bir şirket DTO'su (makul olduğu yerde) döndürmek ve daha sonra görünümün ilgilendiği alanları seçmesine izin vermek doğal olarak yanlış bir şey değildir.
flater

Şimdi bu bana mantıklı geliyor. Çok teşekkürler. Flater.
Arash

Bir soru daha. "İş nesnesi ve bir görünüm nesnesi" dediniz . İkisinin de eşit olduğunu düşündüm. Arama yaptığımda, Business Object'in View Object ile karşılaştırmak için genel bir anlamı olduğunu fark ettim . Ancak İş Nesnesi kullanım durumundan türetilmeli ve Varlık Nesnesi Veri Modelinden türetilmelidir, bu yüzden farklıdırlar, değil mi? biraz açıklayabilir misin lütfen?
Arash

@Arash: "İş nesnesi" ile "görüntüleme nesnesi" olarak adlandırdığınız şey arasındaki fark bağlamdır . İnsanlar için bu ayrım, şeyleri doğru bir şekilde anlamak için önemlidir. Ancak derleyici (ve ayrıca dilin kendisi) aralarında teknik bir fark görmüyor. Aynı olduklarını söylediğimde, bunu teknik bir perspektiften kastediyorum. Her ikisi de sadece veri tutmaya ve aktarılmaya yönelik özelliklere sahip bir sınıftır. Bu bağlamda, aralarında hiçbir fark yoktur.
flater
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.