Düz Eski CLR Nesnesi ve Veri Aktarım Nesnesi


405

POCO = Düz Eski CLR (veya üstü: Sınıf) Nesnesi

DTO = Veri Aktarım Nesnesi

Bu gönderide bir fark var, ancak açıkçası okuduğum blogların çoğu POCO'yu DTO'nun tanımlandığı şekilde tarif ediyor: DTO'lar, verileri bir uygulamanın katmanları arasında taşımak için kullanılan basit veri kaplarıdır.

POCO ve DTO aynı şey midir?


5
"POCO = Düz Eski CLR (veya üstü: Sınıf) Nesnesi". Bu nedenle, VB.NET'teki bu tür nesneler POVO'lar değil, POCO'lar olacaktır.
J. Polfer

Yanıtlar:


568

Bir POCO, OOP kurallarına uyar. Durum ve davranışları olmalıdır (ama zorunlu değildir) . POCO, Martin Fowler [ anecdote ] tarafından icat edilen POJO'dan geliyor . POJO terimini, ağır EJB uygulamalarını çerçeveyi reddetmeyi daha seksi hale getirmenin bir yolu olarak kullandı. POCO, .Net'te aynı bağlamda kullanılmalıdır. Çerçevelerin nesnenizin tasarımını dikte etmesine izin vermeyin.

Bir DTO'nun tek amacı durumu aktarmaktır ve hiçbir davranışı olmamalıdır. Martin Fowler'in bir DTO açıklamasıBu paternin kullanımına ilişkin bir örnek için .

Fark şu: POCO , DTO'nun nesneleri kullanarak "veri aktarımı" için kullanılan bir model olduğu programlama (iyi eski moda nesne yönelimli programlama) yaklaşımını tanımlar .

POCO'lara DTO'lar gibi davranabilmenize rağmen, bunu yaparsanız anemik etki alanı modeli oluşturma riskiyle karşı karşıya kalırsınız. Ek olarak, DTO'ların iş etki alanının gerçek yapısını temsil etmek için değil, veri aktarmak için tasarlanması gerektiğinden yapıda bir uyumsuzluk vardır. Bunun sonucu, DTO'ların gerçek alan adınızdan daha düz olma eğilimindedir.

Herhangi bir makul karmaşıklıkta bir etki alanında, ayrı etki alanı POCO'ları oluşturmak ve bunları DTO'lara çevirmek neredeyse her zaman daha iyidir. DDD (etki alanına dayalı tasarım) yolsuzlukla mücadele katmanını tanımlar ( burada başka bir bağlantı , ancak yapılacak en iyi şey kitabı satın almaktır ), bu da ayrımı netleştiren iyi bir yapıdır.


Burada Martin Fowler'a çok atıfta bulunduğumu biliyorum, ama POJO terimini yazdı ve DTO için kesin referans olan PoEAA kitabını yazdı.
Michael Meadows

Bir DTO'nun davranışları olup olmadığından emin değilim. Martin Fowler'in diyagramına göre DTO'nun davranışları olabilir.
Beatles1692

39
@ Beatles1692, tasvir edilen yöntemler serileştirme kodudur. Muhtemelen "davranış yok" demek çok geniş bir ifadedir. Peki ya "iş mantığı yok". Serileştirme kodu ve karma kodu, eşitlik ve tostring gibi düşük düzeyli nesne öğeleri kabul edilebilir olmalıdır.
Michael Meadows

1
@PositiveGuy Bir model bir DTO'dan farklı bir amaca hizmet eder. DTO, bir alandan diğerine veri aktarmak için olmalıdır (aynı çalışma zamanında olup olmamaları önemli değildir). Model, bir alanın ekran, hizmet veya veri kaynağı gibi bir yönünü "temsil eder". Modeller, modellediklerini temsil eden durum ve davranışı içerir.
Michael Meadows

2
Anemik alan modellerinin özellikle uygulamanız çoğunlukla CRUD olması durumunda kötü olmayabileceğini lütfen unutmayın. Martin Fowler'a sadeliği tercih edin.
Mariusz Jamro

50

Blog makalemdeki konumumu zaten belirttiğim için katkıda bulunmam muhtemelen gereksiz, ancak bu makalenin son paragrafı bir şeyleri özetliyor:

Sonuç olarak, POCO'yu sevmeyi öğrenin ve bir DTO ile aynı şey olduğu konusunda yanlış bilgi yaymadığınızdan emin olun. DTO'lar, verileri bir uygulamanın katmanları arasında taşımak için kullanılan basit veri kaplarıdır. POCO'lar, Kalıcılık Cahili olmaları (alma veya kaydetme yöntemi yok) olmaları şartıyla tam teşekküllü iş nesneleridir. Son olarak, henüz Jimmy Nilsson'un kitabını kontrol etmediyseniz, yerel üniversite yığınlarından alın. C # 'da örnekleri var ve harika bir okuma.

BTW, Patrick POCO'yu bir Yaşam Tarzı makalesi olarak okudum ve tamamen katılıyorum, bu harika bir makale. Aslında Jimmy Nilsson kitabından tavsiye ettiğim bir bölüm. Çevrimiçi olduğunu bilmiyordum. Kitabı gerçekten POCO / DTO / Repository / ve diğer DDD geliştirme uygulamaları hakkında bulduğum en iyi bilgi kaynağı.


4
Blog makalesine bağlantı: rlacovara.blogspot.com/2009/03/…
Jamie Ide

28

POCO, sadece dış bir çerçeveye bağımlı olmayan bir nesnedir. DÜZ.

Bir POCO'nun davranışa sahip olup olmadığı önemsizdir.

Bir DTO, bir etki alanı nesnesi (tipik olarak davranış bakımından zengin olacaktır) gibi POCO olabilir.

Tipik olarak DTO'ların, tipik olarak bir sistemin sınırından çıktıkları için serileştirme amaçları için harici çerçevelere (örn. Öznitelikler) bağımlı olmaları daha olasıdır.

Tipik Soğan tarzı mimarilerde (genellikle geniş bir DDD yaklaşımında kullanılır) etki alanı katmanı merkeze yerleştirilir ve bu nedenle nesnelerinin bu noktada o katmanın dışında bağımlılıkları olmamalıdır.



6

Bence bir DTO bir POCO olabilir. DTO daha çok nesnenin kullanımı ile ilgilidir, POCO ise nesnenin tarzından daha fazladır (mimari konseptlerden ayrıştırılmış).

POCO'nun DTO'dan farklı bir şey olduğu bir örnek, etki alanı modeliniz / iş mantığı modelinizdeki POCO'lardan söz ettiğinizde, sorun alanınızın güzel bir OO temsilidir. Tüm uygulama boyunca POCO'ları kullanabilirsiniz, ancak böyle bir bilgi sızıntısının istenmeyen bir yan etkisi olabilir. DTO'lar örneğin, kullanıcı arayüzünün iletişim kurduğu Hizmet Katmanından kullanılır, DTO'lar verilerin düz bir temsilidir ve yalnızca kullanıcı arayüzüne veri sağlamak ve değişiklikleri hizmet katmanına geri iletmek için kullanılır. Hizmet katmanı, DTO'nun her iki yolunu da POCO etki alanı nesnelerine eşlemekle görevlidir.

Güncelleme Martin Fowler dedi bu yaklaşım almaya ağır bir yoldur ve etki alanı katmanı ve kullanıcı arayüzü arasında anlamlı bir uyumsuzluk varsa sadece alınması gerektiğini.


2
@David Landman, eklediğiniz bağlantı, DTO'lar sistem sınırınızdaki aktarım durumu için kullanıldığında Yerel DTO deseni içindir. Bu durumlarda, çok dikkatli olmalısınız, çünkü sisteminizde zaten paylaşılabilecek iyi tanımlanmış bir etki alanınız olmalıdır. Durumu sistem sınırları içinde aktarırken, DTO'dan kaçınılması zordur ve her durumda oldukça uygundur.
Michael Meadows

@Michal Meadows, evet, bağlantı gerçekten farklı bir sorun alt kümesinden bahsediyor. Ancak devletin bir sistem sınırı boyunca aktarılması durumunda, POCO'yu bir bağlamdan POCO'ya diğer bağlamdan eşlemek için bir çeviri hizmeti kullanmanız gerektiğini düşünüyorum. Yoksa sistem seviyesindeki sınırlamalardan mı bahsediyorsunuz?
Davy Landman

1

Bir DTO için birincil kullanım durumu, bir web hizmetinden veri döndürmektir. Bu durumda, POCO ve DTO eşdeğerdir. POCO'daki herhangi bir davranış, bir web hizmetinden döndürüldüğünde kaldırılır, bu nedenle davranışının olup olmadığı gerçekten önemli değildir.


5
Bence cevabınız biraz olanları yanlış tanıtıyor. Bir web hizmeti söz konusu olduğunda, bir nesnenin açıktaki durumuna bağlı olarak bir proxy oluşturulur. Bu, POCO ile aynı kamu durumuna sahip olan POCO'dan ayrı bir DTO yaratıldığı anlamına gelir. İnce görünebilir, ama önemlidir. Bunun nedeni, proxy orijinal ile aynı olsa bile, aslında aynı sınıftan yapılandırılmamış olmasıdır.
Michael Meadows

Oh hayır. Biri, bu durumda bir web hizmeti olan katmanlar arasında veri döndürmek / almak için bir DTO kullanır. Biri sadece verileri olduğu ve davranışı olmadığı için bir DTO seçer. Proxy sınıfının da muhtemelen bir DTO olacağı ve bunun yerine bir POCO sınıfı kullansaydınız, bir proxy oluşturulacağı doğrudur. Ancak bu durumda, POCO sınıfı etkili bir DTO'dur, çünkü davranışı tercüme edilmeyecektir. Hala DTO kullan diyorum çünkü asla var olmayan davranışları kaçırmayacaksınız.
John Saunders

5
** Anlamsal olarak: Web hizmetleri WSDL kullanarak nesne durum torbalarını ortaya çıkarır. Vekiller bunlardan üretilir. Bunlar davranışları içeremez. Bir web hizmeti tüketiyorsanız, nesneniz ile maruz kalan etki alanı nesnesi arasındaki tek ilişki, incelemeye dayalı olarak aynı genel duruma sahip olmasıdır.
Michael Meadows

7
John, bence aşırı tepki veriyorsun. Haklı olduğunu söylüyorum, ama ifaden yanıltıcı. "Bu durumda, POCO ve DTO eşdeğerdir." Anlamsal olarak, bu doğru değil. POCO'lar DTO olarak kullanılabilir ve bunun tersi de geçerlidir, ancak bu eşdeğer oldukları anlamına gelmez ... ikisi de sizi markete götürmek için kullanılabilse bile, bir araba ve kamyonetten daha fazla eşdeğer değildir. Üst üste binme işlevine sahipler, ancak bakkal gezisi bağlamında bile, bir içgörünün F350'ye eşdeğer olduğunu söyleyecek birini bulmakta zorlanırsınız.
Michael Meadows

3
Bu cevap çok yanlış, bir web servisi biri için yeterince genel değil. En önemlisi, DTO'nun bir POCO DEĞİLDİR. DTO bir veri konteyneriyken, POCO özellik olarak nesnelerdir ve kalıcılık cahilidir (alma veya kaydetme yöntemi yoktur).
Tom Stickel

1

genel kural şudur: DTO == kötü ve aşırı tasarlanmış yazılımın göstergesi. Poco == iyi. 'kurumsal' kalıplar Java EE dünyasındaki birçok insanın beynini yok etti. lütfen hatayı .NET arazisinde tekrarlamayın.


7
Lütfen biraz açıklayabilir misiniz? Sözleşmede uygulama ve platform ayrıntılarından kaçınmak için bir web hizmetinden veri döndürürken DTO gereklidir.
John Saunders

1
Evet, John DTO'lar söyledikleriniz ve iyi çalıştığınız şeyler için tasarlanmıştır. Ancak ne yazık ki, tek katmanlı web uygulamalarında gerekli olmadığında sıklıkla kullanılırlar ve çok az değer taşırlar.
Craig

9
Sanırım, @ drscroogemcduck, belki DTO'lardan hoşlanmıyorsunuz çünkü son çare yerine ilk çare olarak kullanılıyorlar, ancak doğal olarak kötü değiller ... rezil singleton veya fabrika modellerinden daha fazla değil . Kötülük nedir, onları her şey için DTO'lar yapmaya zorlayan geliştiricilerin boğazlarını çerçeveleyen mimarlar. Yaptıkları şey için, veri transferi, DTO'lar (ihtiyatlı bir şekilde yapılırsa) mükemmel uyum sağlar.
Michael Meadows

0

DTO sınıfları, farklı kaynaklardan gelen verilerin serileştirilmesi / serileştirilmesi için kullanılır. Bir nesnenin kaynağından serisini kaldırmak istediğinizde, hangi dış kaynağın olduğu önemli değildir: hizmet, dosya, veritabanı vb. Bunun yalnızca bir kısmını kullanmak isteyebilirsiniz, ancak bu verileri nesne. bundan sonra bu verileri kullanmak istediğiniz XModel'e kopyalarsınız. Bir serileştirici, DTO nesnelerini yüklemek için güzel bir teknolojidir. Neden? nesneyi yüklemek (serisini kaldırmak) için yalnızca bir işleve ihtiyacınız vardır.


0

TL; DR:

Bir DTO, devlet aktarımının biçimini açıklar. Bir POCO hiçbir şey tanımlamaz. OOP'ta "nesne" demenin başka bir yolu. Bu, kelimenin tam anlamıyla 'nesne' için daha süslü bir isim olarak tanımlayan Martin Fowler tarafından kombine edilen POJO'dan (Java) geliyor, çünkü 'nesne' çok seksi değil.

DTO, durumu ilgili katmanlar arasında aktarmak için kullanılan bir nesne modelidir. Bu davranış durumu değiştirmediği sürece davranışları olabilir (teknik olarak bir poco olabilirler). Örneğin, kendini serileştiren bir yöntemi olabilir.

POCO düz bir nesnedir, ancak 'düz' ile kastedilen, özel olmadığıdır. Bu, zımni bir desene sahip olmayan bir CLR nesnesi olduğu anlamına gelir. Genel bir terim. Başka bir çerçeveyle çalışmak için yapılmamıştır. POCO'nuzda[JsonProperty] tüm özelliklerinde veya EF süslemelerine , o zaman bunun bir POCO olmadığını iddia ederim.

Burada karşılaştırılacak farklı nesne desenlerinin bazı örnekleri:

  • Modeli Görüntüle : bir görünümdeki verileri modellemek için kullanılır. Genellikle ciltleme ve doğrulamaya yardımcı olacak veri ek açıklamalarına sahiptir. MVVM'de, aynı zamanda bir kontrolör görevi görür. Bir DTO'dan daha fazlası
  • Değer Nesnesi : değerleri temsil etmek için kullanılır
  • Agrega Kökü : eyalet ve değişmezleri yönetmek için kullanılır
  • İşleyiciler : bir olaya / mesaja yanıt vermek için kullanılır
  • Özellikler : kesişen endişelerle başa çıkmak için dekorasyon olarak kullanılır
  • Hizmet : karmaşık görevleri yerine getirmek için kullanılır
  • Denetleyici : isteklerin ve yanıtların akışını kontrol etmek için kullanılır
  • Fabrika : Bir kurucu yeterince iyi olmadığında kullanılmak üzere karmaşık nesneleri yapılandırmak ve / veya birleştirmek için kullanılır. Ayrıca çalışma zamanında hangi nesnelerin oluşturulması gerektiğine karar vermek için kullanılır.
  • Depo / DAO : verilere erişmek için kullanılır

Bunların hepsi sadece nesnelerdir, ancak çoğunun genellikle bir desene bağlı olduğuna dikkat edin. Böylece onlara “nesneler” diyebilir ya da niyetiyle ilgili daha spesifik olabilir ve ne olduğunu söyleyebilirsiniz. Bu yüzden tasarım kalıplarımız da var; birkaç eserde karmaşık kavramları tanımlamak. DTO bir kalıptır. Agrega kökü bir kalıptır, Görünüm Modeli bir kalıptır (örn. MVC ve MVVM). POCO bir model değildir.

Bir POCO bir patern tanımlamaz. OOP'taki sınıflara / nesnelere atıfta bulunmanın sadece farklı bir yoludur. Bunu soyut bir kavram olarak düşünün; her şeye atıfta bulunabilirler. IMO, tek yönlü bir ilişki var çünkü bir nesne temiz bir şekilde sadece bir amaca hizmet edebileceği noktaya ulaştığında, artık bir POCO değil. Örneğin, bir çerçeveyle çalışmasını sağlamak için sınıfınızı süslemelerle işaretlediğinizde, artık bir POCO değildir. Bu nedenle:

  • DTO bir POCO'dur
  • Bir POCO bir DTO değildir
  • Bir Görünüm Modeli bir POCO'dur
  • POCO bir Görünüm Modeli değildir

İkisi arasında bir ayrım yapmanın amacı, endişeleri aşmamak ve sıkı birleşmeye yol açmamak için kalıpları açık ve tutarlı tutmaktır. Örneğin, durumu değiştirmek için yöntemlere sahip, ancak aynı zamanda bir API uç noktası üzerinden geri gönderilebilmesi için SQL Server VE JsonProperty'ye kaydetmek için EF süslemeleri ile cehenneme dekore edilmiş bir iş nesneniz varsa. Bu nesne değiştirilmeye karşı toleranssızdır ve muhtemelen bazı özelliklerin DB'ye kaydedilmeyecek şekilde işaretlendiği ve diğerlerinin API bitiş noktasında JSON).

Bana bir şeyin DTO olduğunu söyleseydiniz, muhtemelen durumu hareket etmekten başka hiçbir şey için kullanılmadığından emin olurdum. Bana bir görünüm modeli olduğunu söylediyseniz, muhtemelen bir veritabanına kaydedilmediğinden emin olurdum. Bana bir alanın Modeli olduğunu söylediyseniz, muhtemelen alanın dışındaki herhangi bir şeye bağımlılığı olmadığından emin olurdum. Ama bana bir şeyin POCO olduğunu söyleseydin, bana gerçekten fazla bir şey söylemezdin.


-13

Onlara DTO bile demeyin. Onlara Modeller ... Dönemi denir . Modellerde asla davranış yoktur. Bu aptal terim DTO'yu kimin bulduğunu bilmiyorum ama bu bir şey olmalı. MVC'de görünüm modellerini düşünün, aynı baraj ** şey, modeller katmanlar arasında sunucu tarafı veya tel süresi boyunca transfer etmek için kullanılır, hepsi modellerdir. Veri içeren özellikler. Bunlar telden geçirdiğiniz modellerdir. Modeller, Modeller Modeller. Bu kadar.

Keşke aptal DTO terimimizin kelime dağarcığımızdan uzaklaşmasını isterdim.


1
Modellerin asla davranışları olmadığı fikrini nereden aldığını bilmiyorum. Modelleme davranışı olmadan CRUD'dan başka bir şeyi nasıl modellersiniz? ViewModels bile birçok durumda, özellikle MVVM uygulamalarında davranış gösterir. DTO yararlı bir terimdir, çünkü amacı doğru bir şekilde tanımlar; veri aktarımı.
Gerald

9
Aslında yanlış olduğu ve hoşnutsuz tutum için aşağı düştü.
joedotnot

Saçmalık. Modeller aptal kaplar olmalıdır. DTO yoktur, bu bir MS hazırlık terimidir. Modelleri etki alanları, hizmetler ve uygulamalar arasında aktarırsınız. Dönemi. DTO, ihtiyaç duyulmayan bir terim israfıdır ve sadece işleri daha fazla karıştırır. Modeller, Modeller ve daha fazlası Modeller bu kadar. Modellerde davranış olabilir veya olmayabilir. Görünüm Modelleri olmamalıdır. Bu davranış Model sınıfında değil, BL'de olmalıdır.
PositiveGuy

DTO'ların işlevsel model olduğunu kabul ediyorum. ViewModels'in davranışları vardır ve MVVM'de bağlandığınız şey budur. ANCAK, Modellerimin daha akıllı olduğu bir uygulama yazdım (temel olarak VM'ler ama onları aramak istemedim) ve bir DTO nesnesini "kabul ettiler". Bu, çerçeve ile daha fazla seçeneğe sahip olmamı sağladı. Bu yüzden CRUD'dan (hatta EF'den), nesneyi WCF hizmetleri üzerinden iletir ve DTO nesnesini alır ve kapsülleyebilirim (OnProp Değişikliği vb. Ekleyerek). ViewModel'lerim daha fazla kapsülleme yaptı ve iki "Model" i (veya bir listeyi) kabul etmiş olabilir. Katı tanım VM'lerdir.
SQLMason

"Modelleri etki alanları, hizmetler ve uygulamalar arasında aktarıyorsunuz" Açıkladığınız bu davranış için model terimi neden DTO teriminden daha uygun ve daha uygun?
Caa
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.