Mengapa objek transfer data (DTO) merupakan anti-pola?

132

Saya baru-baru ini mendengar orang mengatakan bahwa objek transfer data (DTO) adalah anti-pola .

Mengapa? Apa saja alternatifnya?

ntownsend
sumber
11
Mungkin karena objek bisnis mampu mentransportasikan datanya sendiri, terima kasih banyak!
Zoidberg
13
"Anti-pola" mungkin menjadi calon saya untuk "frasa yang 15 menit sudah lama berlalu." Ini identik dengan "Saya tidak peduli untuk membenarkan pemikiran saya" sekarang, seperti "Sudah diketahui bahwa ..."
Craig Stuntz
6
Zoidberg, mengirimkan objek dengan metode melalui kawat memberi kami CORBA, DCOM, dan pengalaman lain yang saya coba hapus ingatan saya. Masalahnya adalah, cepat atau lambat orang ingin memanggil metode itu.
Craig Stuntz
10
DTOs mewujudkan prinsip KERING, yang sayangnya di J2EE singkatan do ulangi sendiri.
joeforker
Anda mungkin ingin membaca ini: Data Transfer Object Is a Shame
yegor256

Jawaban:

139

Beberapa proyek memiliki semua data dua kali . Sekali sebagai objek domain, dan sekali sebagai objek transfer data.

Duplikasi ini memiliki biaya besar , sehingga arsitektur perlu mendapatkan manfaat besar dari pemisahan ini agar sepadan.

KLE
sumber
5
Tolong jelaskan "biaya besar". Juga, katakan mengapa biaya tidak dapat dihilangkan dengan menggunakan teknik pembuatan kode untuk menghasilkan kelas DTO.
John Saunders
70
+1. Dua kali? Hanya jika Anda beruntung :-) Proyek-proyek yang menduplikasi entitas domain sebagai DTO juga cenderung memiliki kacang UI yang hampir sama-tapi-oh-jadi-agak-berbeda untuk melengkapi mereka. Itu 3. Dan jika, Tuhan melarang, ada semacam remoting (layanan web / xml-rpc / apa pun) yang terjadi, Anda dapat dengan mudah mencapai 4 atau 5.
ChssPly76
17
Saya saat ini bekerja dengan arsitektur lasagna 14 layer enterpricy (BUKAN KIDDING). Saya dapat meyakinkan Anda bahwa 11-atau lebih lapisan yang terutama untuk data-transer tidak datang secara gratis.
KarlP
10
Juga, sementara saya benar-benar menyukai generator kode ketika bekerja dengan desain yang bodoh, mereka adalah a) hal yang pasti Anda salah melakukannya sejak awal. b) mereka tidak datang secara gratis.
KarlP
7
Maaf, tapi ini hanya salah dan jawaban yang salah terpilih dan diterima. Pertama-tama Anda dapat menggunakan refleksi untuk menghasilkan DTO dengan cepat. Kedua, Anda dapat menggunakan "definisi root" misalnya dalam sistem KASUS atau dalam oAW dan menghasilkan BO dan DTO (s). Ketiga, Anda dapat menggunakan XSD dan JAXB untuk menghasilkan DTO dan menggunakan DTO sebagai basis untuk BO, atau Anda dapat menghasilkan keduanya dari XSD ... tetap, jika ada yang berani mentransfer EJB yang baru diambil dari DB melalui kawat ke program klien ... di lingkungan tempat saya bekerja, kepalanya akan berada di piring perak segera ...
Angel O'Sphere
128

DTO bukan merupakan anti-pola. Saat Anda mengirim beberapa data melalui kabel (katakanlah, ke halaman web dalam panggilan Ajax), Anda ingin memastikan bahwa Anda menghemat bandwidth dengan hanya mengirim data yang tujuan akan gunakan. Juga, sering kali nyaman bagi lapisan presentasi untuk memiliki data dalam format yang sedikit berbeda dari objek bisnis asli.

Saya tahu ini adalah pertanyaan berorientasi Java, tetapi dalam bahasa .NET jenis anonim, serialisasi, dan LINQ memungkinkan DTO dibuat secara langsung, yang mengurangi pengaturan dan overhead penggunaannya.

Gabe Moothart
sumber
15
@ John, Ini tidak benar. Saya selalu melakukannya. Serialisasi menggunakan refleksi, yang berfungsi dengan baik pada jenis anonim. Cukup serahkan ke serializer sebagai objek. Dan begitu serialisasi (ke xml atau json, misalnya) tentu saja Anda dapat mengembalikannya dari suatu metode.
Gabe Moothart
8
Um, John, itu tidak benar. Anda dapat membuat serial jenis anonim ke JSON dengan baik. Cobalah di aplikasi MVC: kembalikan Json (baru {Foo = "Hai di sana!}); Saya berjanji Anda akan bekerja dengan baik. Lebih baik, mungkin, daripada jenis non-anonim, karena jenis anonim umumnya tidak memiliki siklus dalam grafik objek mereka , yang mematahkan serializer JSON
282 Craig Stuntz
1
Serialisasi Json bukan DTO dalam hal ini, dan karenanya tidak berlaku. Maka tentu saja, argumen saya di atas berlaku juga, pada titik tertentu, mereka hanya berhenti sepadan.
Jim Barrows
1
Gabe benar, DTO bukan anti-pola per se (tetapi bisa jika digunakan secara tidak benar!) Ketika tidak ada duplikasi data. Misalnya, BO dapat mengumpulkan data dari berbagai sumber menjadi DTO.
astro
3
+1. Dan ada banyak alasan lain selain konservasi bandwidth yang Anda inginkan DTO. Apakah Anda bahkan DIIZINKAN (berdasarkan kebijakan atau hukum perusahaan) untuk mengirim setiap bidang melalui kawat? Juga, di perusahaan kami, DAO kami sangat kompleks karena perlu melakukan semua optimasi ini - bekerja di lapisan layanan, saya sangat senang mereka menggunakan DTO dan tidak membuat kami khawatir tentang hubungan yang dimiliki Obyek X ke beberapa tabel n-to-n lainnya.
user64141
25

DTO an AntiPattern di EJB 3.0 mengatakan:

Sifat berat Entity Beans dalam spesifikasi EJB sebelum EJB 3.0, menghasilkan penggunaan pola desain seperti Data Transfer Objects (DTO). DTO menjadi objek ringan (yang seharusnya menjadi entitas entitas sendiri di tempat pertama), yang digunakan untuk mengirim data melintasi tingkatan ... sekarang spesifikasi EJB 3.0 membuat model kacang Entitas sama dengan objek Java kuno (POJO). Dengan model POJO baru ini, Anda tidak perlu lagi membuat DTO untuk setiap entitas atau untuk sekumpulan entitas ... Jika Anda ingin mengirim entitas EJB 3.0 di tier, buat mereka hanya mengimplementasikan java.io.Serialiazable

aem
sumber
6
Benar ketika Anda mentransfer objek antara metode dalam JVM yang sama, di memori. Tidak benar ketika Anda benar-benar membuat cerita bersambung melalui kawat dan ingin mengontrol seberapa dalam membuat cerita bersambung, dan / atau mempertahankan pemuatan yang malas.
wrschneider
Ya, dan bahkan di JVM yang sama, Anda harus benar-benar berhati-hati untuk tetap berada di thead yang sama jika Anda menggunakan manajemen transaksional JEE / Spring.
Marc
20

Saya tidak berpikir DTO adalah anti-pola per se, tetapi ada antipattern yang terkait dengan penggunaan DTO. Bill Dudney menyebut ledakan DTO sebagai contoh:

http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf

Ada juga sejumlah penyalahgunaan DTO yang disebutkan di sini:

http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/

Mereka berasal karena tiga sistem tingkat (biasanya menggunakan EJB sebagai teknologi) sebagai sarana untuk mengirimkan data antar tingkatan. Sebagian besar sistem Java modern berdasarkan kerangka kerja seperti Spring mengambil tampilan alternatif yang disederhanakan menggunakan POJO sebagai objek domain (sering dijelaskan dengan JPA dll ...) dalam satu tingkat ... Penggunaan DTO di sini tidak perlu.

Jon
sumber
3
Anda sepenuhnya benar bahwa DTO adalah pola yang baik , bukan anti-pola, ketika digunakan dalam konteks yang tepat. Tautan kedua Anda tampaknya sudah mati sekarang, tetapi penyalahgunaan terbesar yang saya lihat adalah di mana setiap objek domain memiliki "DTO" yang sesuai untuk interaksi basis data yang tidak menambah nilai dan sama sekali bukan DTO!
David
19

OO purists akan mengatakan bahwa DTO adalah anti-pola karena objek menjadi representasi tabel data, bukan objek domain nyata.

Darin Dimitrov
sumber
9

Beberapa menganggap DTO sebagai anti-pola karena kemungkinan penyalahgunaannya. Mereka sering digunakan ketika mereka seharusnya / tidak perlu.

Artikel ini secara samar-samar menjelaskan beberapa pelanggaran.

Ben S
sumber
1
Artikel ini jauh lebih akurat menggambarkan DTO sebagai pola yang dapat disalahgunakan.
Craig Stuntz
Ini sama dengan jawaban tautan saja, itu benar-benar membutuhkan setidaknya kutipan dari artikel. tidak tahu bagaimana ini berhasil tidak ditandai sebagai Bukan Jawaban.
Nathan Hughes
7

Jika Anda sedang membangun sistem terdistribusi, maka DTO tentu bukan pola anti. Tidak semua orang akan berkembang dalam pengertian itu, tetapi jika Anda memiliki (misalnya) aplikasi Sosial Buka semua yang menjalankan JavaScript.

Ini akan mengirim banyak data ke API Anda. Ini kemudian dideserialisasikan ke dalam beberapa bentuk objek, biasanya objek DTO / Permintaan. Ini kemudian dapat divalidasi untuk memastikan data yang dimasukkan benar sebelum dikonversi menjadi objek model.

Menurut pendapat saya, ini dianggap sebagai anti-pola karena salah digunakan. Jika Anda tidak membangun sistem terdistribusi, kemungkinan Anda tidak membutuhkannya.

Bealer
sumber
4

Tujuan dari Obyek Transfer Data adalah untuk menyimpan data dari sumber yang berbeda dan kemudian mentransfernya ke dalam basis data (atau Remote Facade ) sekaligus.

Namun, pola DTO melanggar Prinsip Tanggung Jawab Tunggal , karena DTO tidak hanya menyimpan data, tetapi juga mentransfernya dari atau ke basis data / fasad.

Kebutuhan untuk memisahkan objek data dari objek bisnis bukan antipattern, karena mungkin diperlukan untuk memisahkan lapisan database .

Alih-alih DTO Anda harus menggunakan Pola Agregat dan Repositori, yang memisahkan kumpulan objek ( Agregat ) dan transfer data ( Repositori ).

Untuk mentransfer sekelompok objek, Anda dapat menggunakan pola Unit Kerja , yang menampung satu set Repositori dan konteks transaksi; untuk mentransfer setiap objek dalam agregat secara terpisah dalam transaksi.

MovGP0
sumber
4

DTO menjadi suatu keharusan dan bukan POLA ANTI ketika Anda memiliki semua objek domain Anda memuat objek yang terkait dengan EAGERly.

Jika Anda tidak membuat DTO, Anda akan memiliki objek yang ditransfer tidak perlu dari lapisan bisnis Anda ke klien / lapisan web Anda.

Untuk membatasi overhead untuk kasus ini, alih-alih transfer DTO.

javadev
sumber
1

Pertanyaannya seharusnya bukan "mengapa", tetapi " kapan ".

Jelas itu anti-pola ketika hanya hasil menggunakannya lebih mahal - run-time atau pemeliharaan. Saya bekerja pada proyek yang memiliki ratusan DTO identik dengan kelas entitas basis data. Setiap kali Anda ingin menambahkan satu bidang yang Anda iklan tambahkan id seperti empat kali - ke DTO, ke entitas, ke konversi dari DTO ke kelas domain atau entitas, konversi terbalik, ... Anda lupa beberapa tempat dan data yang didapat tidak konsisten.

Ini bukan anti-pola ketika Anda benar-benar membutuhkan representasi kelas domain yang berbeda - lebih datar, lebih kaya, lebih sempit, ...

Secara pribadi saya mulai dengan kelas domain dan menyebarkannya, dengan pemeriksaan yang tepat di tempat yang tepat. Saya dapat membuat anotasi dan / atau menambahkan beberapa kelas "pembantu" untuk membuat pemetaan, ke database, ke format serialisasi seperti JSON atau XML ... Saya selalu dapat membagi kelas menjadi dua jika saya merasa perlu.

Ini tentang sudut pandang Anda - Saya lebih suka melihat objek domain sebagai objek tunggal yang memainkan berbagai peran, daripada beberapa objek yang dibuat dari satu sama lain. Jika satu-satunya peran objek adalah mengangkut data, maka itu DTO.

Rostislav Matl
sumber
1

Saya pikir orang-orang berarti itu bisa menjadi anti-pola jika Anda menerapkan semua objek jarak jauh sebagai DTO. DTO hanyalah sekedar sekumpulan atribut dan jika Anda memiliki objek besar, Anda akan selalu mentransfer semua atribut bahkan jika Anda tidak membutuhkan atau menggunakannya. Dalam kasus terakhir lebih suka menggunakan pola Proxy.

jdehaan
sumber