Entitas untuk Penggunaan DTO

15

Telah mencoba membuat alur untuk aplikasi web berjenjang dasar, dan telah membaca informasi yang saling bertentangan secara online. Yang saya coba cari tahu adalah apakah ada keuntungan untuk tetap menggunakan objek DTO dari DAO Anda ke lapisan Layanan melalui penggunaan semacam mapper.

Aliran dasar yang saya ramalkan adalah sebagai berikut:

  1. Model / Formulir UI -> Pengontrol
  2. Pengendali mengubah Model menjadi Objek Domain (Entitas)
  3. Objek Domain -> Lapisan Layanan
  4. Objek Domain -> DAO
  5. DAO -> Objek Domain
  6. Layanan -> UI
  7. UI mengubah Domain menjadi model UI

Jika DTO diikuti, DAO akan mengembalikan DTO bukan Entitas. Setelah melakukan beberapa pembacaan sepertinya DTO telah menjadi sedikit tidak aktif sejak (setidaknya di Jawa) entitas telah menjadi POJO beranotasi yang berarti jejak memori mereka menjadi sangat kecil.

Apakah ini masalahnya, atau apakah DTO harus digunakan untuk merangkum sepenuhnya objek domain dalam lapisan DAO, dan, jika demikian, lapisan layanan apa yang akan diteruskan ke DAO?

Terima kasih banyak!

Dardo
sumber

Jawaban:

20

Menurut saya, melewati POJO yang persisten, seperti misalnya kacang yang dikelola oleh JPA, bukanlah praktik yang baik.

Mengapa?

Saya melihat tiga alasan utama:

  1. Masalah potensial dengan koleksi malas. http://java.dzone.com/articles/avoid-lazy-jpa-collections
  2. Entity harus berisi perilaku (bertentangan dengan model domain Anemic ) Anda mungkin tidak ingin membiarkan UI Anda memanggil beberapa perilaku tak terduga.
  3. Dalam kasus model domain anemia, Anda mungkin tidak ingin mengekspos struktur model Anda ke UI, karena setiap perubahan baru pada model dapat merusak UI.

Saya lebih suka membiarkan lapisan layanan saya mengkonversi entitas ke DTO yang sesuai di kedua arah. DAO masih mengembalikan entitas (bukan tugasnya untuk memastikan konversi).

Mik378
sumber
Jadi jika saya memahami ini dengan benar, layanan ini pada dasarnya hanya berurusan dengan objek DTO, dan bertindak sebagai perantara UI dan DAO. Juga, pada poin 3, Anda masih harus mengonversi DTO Anda menjadi elemen UI yang bisa diterapkan, jadi bukankah pembaruan domain masih merusak UI karena DTO juga memerlukan pembaruan.
Dardo
1
@dardo elemen UI ADALAH DTO, atau paling buruk, harus dikonversi ke DTO sebelum memanggil beberapa layanan di sisi server. DTO tidak cenderung sering berubah, hanya ada adaptasi dari entitas Anda yang berfokus pada kebutuhan UI. Selain itu, lapisan layanan harus memperhatikan keduanya: DTO dan entitas.
Mik378
Ah ok, ada cegukan yang tidak saya mengerti. Model domain anemik cukup umum di tempat saya bekerja, dan saya mencoba untuk menggeser paradigma sedikit untuk mendorong lapisan layanan yang lebih tipis. Terima kasih lagi!
dardo
@dardo Anda dapat membaca buku ini. (atau tunjukkan pada perusahaan Anda;)) Buku hebat: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
sebenarnya punya yang ini di kindle, amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/… lumayan bagus sejauh ini = D
dardo
13

Salah satu alasan saya pikir diskusi ini muncul berulang kali adalah karena tampaknya seperti kesakitan serius untuk mengambil objek dengan semua data yang Anda butuhkan dan mengubahnya menjadi objek yang terlihat identik atau hampir identik dengan yang ada. kamu menyerahkan

Memang benar, itu adalah PITA. Tetapi ada beberapa alasan (selain yang disebutkan di atas) untuk melakukannya.

  • Objek domain bisa menjadi sangat berat dan mengandung banyak informasi yang tidak berguna untuk panggilan. Kembung ini memperlambat UI karena semua data dikirimkan, disusun / tidak dikunci dan diuraikan. Ketika Anda mempertimbangkan FE akan memiliki banyak tautan yang merujuk ke layanan web Anda dan dipanggil dengan AJAX atau pendekatan multi-utas lainnya, Anda akan dengan cepat membuat UI Anda lamban. Semua ini sampai pada skalabilitas umum layanan web
  • Keamanan dapat dengan mudah dikompromikan dengan mengekspos terlalu banyak data. Minimal Anda dapat mengekspos alamat email dan nomor telepon pengguna jika Anda tidak menghilangkannya dari hasil DTO.
  • Pertimbangan praktis: Untuk 1 objek yang diarak sebagai objek domain yang bertahan DAN DTO, ia harus memiliki lebih banyak anotasi daripada kode. Anda akan memiliki sejumlah masalah dengan mengelola keadaan objek saat melewati lapisan. Secara umum ini menjadi jauh lebih PITA untuk mengelola kemudian hanya melakukan kebosanan menyalin bidang dari objek domain ke DTO.

Tetapi, Anda dapat mengelolanya dengan cukup efektif jika Anda merangkum logika terjemahan ke dalam kumpulan kelas konverter

Lihat lambdaJ di mana Anda dapat melakukan 'convert (domainObj, toDto)' ada kelebihan ini untuk digunakan dengan koleksi. Berikut adalah contoh metode pengontrol yang memanfaatkannya. Seperti yang Anda lihat, itu tidak terlihat terlalu buruk.

    @GET
    @Path("/{id}/surveys")
    public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {

        checkDateRange(from, to);

        MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
        Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
        return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);

    }
Christian Bongiorno
sumber
Terima kasih atas masukannya, dan pemikiran saya sejalan =)
dardo