Apa itu Objek Transfer Data?

217

Apa itu Objek Transfer Data?

Dalam MVC adalah kelas model DTO, dan jika tidak apa perbedaannya dan apakah kita membutuhkan keduanya?

Yaron Naveh
sumber
@ yegor256 dan faktanya, buku di artikel itu tahu cara mengambil data dari API dan juga cara menyimpan data ke DB, dan dengan demikian melanggar SRP, ok?
Betlista

Jawaban:

222

Objek Transfer Data adalah objek yang digunakan untuk merangkum data, dan mengirimkannya dari satu subsistem aplikasi ke yang lain.

DTO paling umum digunakan oleh lapisan Layanan dalam aplikasi N-Tier untuk mentransfer data antara dirinya dan lapisan UI. Manfaat utama di sini adalah mengurangi jumlah data yang perlu dikirim melintasi kabel dalam aplikasi terdistribusi. Mereka juga membuat model hebat dalam pola MVC.

Penggunaan lain untuk DTO dapat untuk merangkum parameter untuk panggilan metode. Ini dapat bermanfaat jika suatu metode mengambil lebih dari 4 atau 5 parameter.

Saat menggunakan pola DTO, Anda juga akan menggunakan perakit DTO. Assembler digunakan untuk membuat DTO dari Objek Domain, dan sebaliknya.

Konversi dari Domain Object ke DTO dan kembali lagi dapat menjadi proses yang mahal. Jika Anda tidak membuat aplikasi terdistribusi, Anda mungkin tidak akan melihat manfaat besar dari polanya, seperti dijelaskan Martin Fowler di sini

Benny Hallett
sumber
7
"DTO membuat model hebat dalam pola MVC" - tetapi bukankah model harus berisi semua data objek dan DTO dioptimalkan dengan bagian dari data? Jika saya memiliki model A dan saya harus meneruskannya ke dua subsistem, apakah akan ada A_DTO_1 dan A_DTO_2 dengan bidang masing-masing yang relevan? "DTO bisa untuk merangkum parameter untuk pemanggilan metode" -> Jadi setiap kelas yang membungkus parameter adalah DTO bahkan jika ini bukan sistem terdistribusi? Bukankah model dalam MVC objek domain?
Yaron Naveh
2
Sebagai jawaban untuk pertanyaan pertama Anda, saya pikir tidak membicarakan hal yang sama. Model dalam MVC tidak harus berupa kelas dari Model Domain Anda. Karena itu, itu bisa saja. Menggunakan DTO menghapus semua hal yang tidak perlu. Tergantung pada arsitektur yang Anda tuju. Saya tidak yakin bagaimana menjawab pertanyaan kedua Anda. Apakah itu melintasi kabel atau tidak, itu masih merupakan objek yang mengenkapsulasi banyak data untuk ditransfer antara (sub) sistem, jadi saya berpendapat itu adalah DTO.
Benny Hallett
12
"Penggunaan lain untuk DTO dapat untuk merangkum parameter untuk panggilan metode. Ini dapat berguna jika metode mengambil lebih dari 4 atau 5 parameter." Ini sebenarnya anti-pola yang disebut kelas Poltergeist atau Gypsy Wagon. Jika metode Anda membutuhkan 4 argumen lalu berikan 4, jangan membuat kelas hanya untuk memindahkan objek ke metode atau kelas.
Wix
2
@ Win, poin bagus. Namun saya berpendapat bahwa ini ok jika secara semantik benar (katakanlah jika Anda melewati kelas pengaturan dengan properti daripada properti itu sendiri sebagai nilai). Apa yang tidak boleh Anda lakukan adalah melemparkan semua argumen demi melewati satu objek, karena mereka mungkin tidak berhubungan dan menyebabkan mimpi buruk terurai nanti.
Aram Kocharyan
3
DTO tidak boleh digunakan untuk merangkum parameter untuk pemanggilan metode (yang akan membuatnya menjadi LocalDTO), mereka diperkenalkan dalam konteks antarmuka jarak jauh: martinfowler.com/bliki/LocalDTO.html
Rui
28

Definisi untuk DTO dapat ditemukan di situs Martin Fowler . DTO digunakan untuk mentransfer parameter ke metode dan sebagai tipe pengembalian. Banyak orang menggunakan itu di UI, tetapi yang lain mengembang objek domain dari mereka.

blu
sumber
22

DTO adalah objek bodoh - ia hanya menampung properti dan memiliki getter dan setter, tetapi tidak ada logika lain yang signifikansi (selain mungkin implementasi perbandingan () atau equals ()).

Biasanya model kelas dalam MVC (dengan asumsi .net MVC di sini) adalah DTO, atau koleksi / agregat DTO

Eric Petroelje
sumber
3
Apa yang Anda gambarkan adalah LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui
3
Satu kasus di mana berguna untuk menggunakan sesuatu seperti DTO adalah ketika Anda memiliki ketidakcocokan yang signifikan antara model di lapisan presentasi Anda dan model domain yang mendasarinya. Dalam hal ini masuk akal untuk membuat fasad / gateway khusus presentasi yang memetakan dari model domain dan menyajikan antarmuka yang nyaman untuk presentasi.
Amitābha
14

Secara umum, Nilai Objek harus tidak berubah. Seperti objek Integer atau String di Java. Kita dapat menggunakannya untuk mentransfer data antar lapisan perangkat lunak. Jika lapisan atau layanan perangkat lunak berjalan di node jarak jauh yang berbeda seperti di lingkungan layanan microser atau di Java Enterprise App yang lama. Kita harus membuat salinan yang hampir pasti dari dua kelas. Di sinilah kami bertemu DTO.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

Dalam DTO Java Enterprise Systems warisan dapat memiliki berbagai hal EJB di dalamnya.

Saya tidak tahu ini adalah praktik terbaik atau tidak, tetapi saya pribadi menggunakan Value Objects di Spring MVC / Boot Projects saya seperti ini:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

Lapisan pengontrol tidak tahu entitas apa. Ini berkomunikasi dengan Formulir dan Lihat Nilai Objek . Formulir Objek memiliki anotasi Validasi JSR 303 (misalnya @NotNull) dan Objek Nilai Tampilan memiliki Anotasi Jackson untuk serialisasi kustom. (misalnya @JsonIgnore)

Lapisan layanan berkomunikasi dengan lapisan repositori melalui menggunakan Objek Entitas. Objek entitas memiliki anotasi JPA / Hibernate / Spring Data di atasnya. Setiap lapisan berkomunikasi hanya dengan lapisan bawah. Komunikasi antar-lapisan dilarang karena ketergantungan melingkar / siklik.

User Service ----> XX CANNOT CALL XX ----> Order Service

Beberapa Kerangka ORM memiliki kemampuan proyeksi melalui penggunaan antarmuka atau kelas tambahan. Jadi repositori dapat mengembalikan objek View secara langsung. Untuk itu Anda tidak perlu transformasi tambahan.

Misalnya ini adalah entitas Pengguna kami:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

Tetapi Anda harus mengembalikan daftar pengguna yang dikotak-kotakkan yang hanya menyertakan id, nama depan, nama belakang. Kemudian Anda bisa membuat View Value Object untuk proyeksi ORM.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

Anda dapat dengan mudah mendapatkan hasil paginasi dari lapisan repositori. Berkat pegas Anda juga dapat menggunakan antarmuka yang adil untuk proyeksi.

List<UserListItemView> find(Pageable pageable);

Jangan khawatir karena BeanUtils.copymetode operasi konversi lainnya berfungsi dengan baik.

Fırat KÜÇÜK
sumber
11
  1. Bagi saya jawaban terbaik untuk pertanyaan apa itu DTO adalah bahwa DTO adalah objek sederhana yang tidak boleh mengandung logika bisnis atau implementasi metode apa pun yang memerlukan pengujian .
  2. Biasanya model Anda (menggunakan pola MVC) adalah model yang cerdas, dan mereka dapat berisi banyak / beberapa metode yang melakukan beberapa operasi berbeda untuk model itu secara khusus (bukan logika bisnis, ini harus di controller). Namun, ketika Anda mentransfer data (mis. Memanggil titik akhir REST ( GET/ POST/ apa pun) dari suatu tempat, atau menggunakan layanan web menggunakan SOA, dll ...) Anda tidak ingin mengirimkan objek berukuran besar dengan kode yang tidak diperlukan untuk titik akhir, akan mengkonsumsi data, dan memperlambat transfer.
Thiago Burgos
sumber
Mengapa logika bisnis harus di controller?
AlexioVay
6

Dengan MVC, objek transfer data sering digunakan untuk memetakan model domain ke objek yang lebih sederhana yang pada akhirnya akan ditampilkan oleh tampilan.

Dari Wikipedia :

Objek transfer data (DTO), sebelumnya dikenal sebagai objek nilai atau VO, adalah pola desain yang digunakan untuk mentransfer data antara subsistem aplikasi perangkat lunak. DTO sering digunakan bersama dengan objek akses data untuk mengambil data dari database.

Dan
sumber
3
Objek nilai bukan DTO .
coderpc
0

Objek transfer data (DTO) menjelaskan "objek yang membawa data antar proses" (Wikipedia) atau "objek yang digunakan untuk merangkum data, dan mengirimkannya dari satu subsistem aplikasi ke yang lain" (Stack Overflow answer).

mostafa kazemi
sumber
0

DefN

DTO adalah model data hardcoded . Ini hanya memecahkan masalah pemodelan catatan data yang ditangani oleh proses produksi hardcoded , di mana semua bidang diketahui pada waktu kompilasi dan karenanya diakses melalui properti yang diketik dengan kuat.

Sebaliknya, model dinamis atau "tas properti" memecahkan masalah pemodelan catatan data saat proses produksi dibuat saat runtime.

Cvar

DTO dapat dimodelkan dengan bidang atau properti, tetapi seseorang menemukan wadah data yang sangat berguna yang disebut Cvar. Ini adalah referensi nilai. Ketika DTO dimodelkan dengan apa yang saya sebut properti referensi , modul dapat dikonfigurasikan untuk berbagi memori tumpukan dan dengan demikian bekerja sama di atasnya. Ini sepenuhnya menghilangkan parameter yang lewat dan komunikasi O2O dari kode Anda. Dengan kata lain, DTO yang memiliki properti referensi memungkinkan kode untuk mencapai zero coupling .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

Sumber: http://www.powersemantics.com/

DTO dinamis adalah komponen yang diperlukan untuk perangkat lunak dinamis. Untuk membuat instance proses dinamis, salah satu langkah kompiler adalah mengikat setiap mesin dalam skrip ke properti referensi yang ditentukan skrip. DTO dinamis dibangun dengan menambahkan Cvars ke koleksi.

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

Perselisihan

Catatan: karena Wix memberi label penggunaan DTO untuk mengatur parameter sebagai "anti-pola", saya akan memberikan pendapat resmi.

    return View(model);  // MVC disagrees

Arsitektur kolaboratif saya menggantikan pola desain. Lihat artikel web saya.

Parameter memberikan kontrol langsung pada mesin rangka tumpukan. Jika Anda menggunakan kontrol terus menerus dan karenanya tidak perlu kontrol langsung, modul Anda tidak perlu parameter. Arsitektur saya tidak punya. Konfigurasi dalam proses mesin (metode) menambah kompleksitas tetapi juga nilai (kinerja) ketika parameter adalah tipe nilai. Namun, parameter tipe referensi membuat konsumen menyebabkan cache salah untuk mendapatkan nilai dari heap - oleh karena itu, konfigurasikan saja konsumen dengan properti referensi. Fakta dari teknik mesin: ketergantungan pada parameter adalah semacam pra-optimasi, karena pemrosesan (pembuatan komponen) itu sendiri adalah pemborosan. Lihat artikel W saya untuk informasi lebih lanjut. http://www.powersemantics.com/w.html .

Fowler dan perusahaan mungkin menyadari manfaat DTO di luar arsitektur terdistribusi jika mereka pernah tahu arsitektur lain. Programmer hanya tahu sistem terdistribusi. Sistem kolaboratif terintegrasi (alias produksi alias manufaktur) adalah sesuatu yang harus saya klaim sebagai arsitektur saya sendiri, karena saya adalah orang pertama yang menulis kode dengan cara ini.

Beberapa orang menganggap DTO sebagai model domain anemik, artinya tidak memiliki fungsionalitas, tetapi ini mengasumsikan objek harus memiliki data yang berinteraksi dengannya. Model konseptual ini kemudian memaksa Anda untuk mengirimkan data antar objek, yang merupakan model untuk pemrosesan terdistribusi. Namun pada jalur produksi, setiap langkah dapat mengakses produk akhir dan mengubahnya tanpa memiliki atau mengendalikannya. Itulah perbedaan antara pemrosesan terdistribusi dan terintegrasi. Manufaktur memisahkan produk dari operasi dan logistik.

Tidak ada yang salah dengan pemrosesan model sebagai sekelompok pekerja kantor yang tidak berguna yang saling mengirim email satu sama lain tanpa menyimpan jejak email, kecuali untuk semua pekerjaan tambahan dan sakit kepala yang diciptakannya dalam menangani logistik dan mengembalikan masalah. Proses terdistribusi yang dimodelkan dengan benar melampirkan dokumen (perutean aktif) ke produk yang menjelaskan dari mana operasi itu berasal dan akan pergi ke. Perutean aktif adalah salinan dari perutean sumber proses, yang ditulis sebelum proses dimulai. Jika terjadi kerusakan atau perubahan darurat lainnya, perutean aktif dimodifikasi untuk menyertakan langkah-langkah operasi yang akan dikirim. Ini kemudian menjelaskan semua tenaga kerja yang masuk ke produksi.

RBJ
sumber