Apakah saya salah dalam berpikir bahwa memerlukan sesuatu seperti AutoMapper merupakan indikasi dari desain yang buruk?


35

Automapper adalah "object-object mapper" untuk .Net, yang berarti menyalin objek dari kelas ke kelas lain yang mewakili hal yang sama.

Mengapa ini bermanfaat? Apakah duplikasi kelas bermanfaat / desain bagus?


Referensi kecil: devtrends.co.uk/blog/... Khususnya baca bagian "mengapa kita tidak bisa menggunakan automapper?"
Jani Hyytiäinen

Jawaban:


28

Pencarian google cepat mengungkapkan contoh ini:

http://www.codeproject.com/Articles/61629/AutoMapper

menunjukkan penggunaan AutoMapper yang benar-benar valid yang jelas bukan contoh untuk desain yang buruk. Dalam aplikasi berlapis, Anda mungkin memiliki objek di data atau lapisan bisnis Anda, dan kadang-kadang Anda hanya perlu subset dari atribut objek data itu, atau semacam tampilan di lapisan UI Anda. Jadi Anda membuat model tampilan yang berisi objek dengan atribut yang tepat Anda butuhkan di UI Anda, tidak lebih, dan menggunakan AutoMapper untuk memberikan konten objek dengan kode boilerplate lebih sedikit.

Dalam situasi seperti itu "objek tampilan" Anda bukan duplikat dari kelas asli. Mereka memiliki metode yang berbeda dan mungkin beberapa atribut duplikat. Tapi itu tidak masalah selama Anda menggunakan objek tampilan itu hanya untuk tujuan tampilan UI dan jangan mulai menyalahgunakannya untuk manipulasi data atau operasi bisnis.

Topik lain yang mungkin Anda baca untuk mendapatkan pemahaman yang lebih baik tentang hal ini adalah pola Pemisahan Tanggung Jawab Kueri Perintah Fowlers , berbeda dengan CRUD. Ini menunjukkan kepada Anda situasi di mana model objek yang berbeda untuk meminta data dan memperbarui mereka dalam database masuk akal. Di sini, pemetaan dari satu model objek ke yang lain juga dapat dilakukan oleh alat seperti AutoMapper.


1
Mengenai contoh pertama Anda: tidak bisakah Anda membuat objek alih-alih menduplikasinya? Dalam hal itu objek UI Anda akan memiliki referensi ke objek data asli Anda, dan hanya akan mengekspos elemen yang diperlukan. Bukankah itu masuk akal?
static_rtti

1
@static_rtti dalam teori ya, tetapi Anda mungkin tidak perlu ingin kelas asli Anda menjadi publik atau / dan diekspos dalam sebuah majelis
Jalayn

2
@static_rtti: ya, itu adalah pendekatan yang benar-benar valid dan berbeda. Perbedaan utama antara kedua desain adalah masa pakai data / atribut. Menggunakan salinan memberi Anda snapshot data, menggunakan properti yang merujuk data asli tidak. Kedua pendekatan memiliki pro dan kontra, tetapi IMHO tidak ada "lebih baik atau lebih buruk" secara umum. Selain itu, mungkin ada pertimbangan kinerja, yang mungkin atau mungkin tidak mempengaruhi keputusan apa yang akan digunakan.
Doc Brown

3
Memisahkan sebanyak mungkin selalu merupakan ide yang bagus. Bukan karena itu sangat bermanfaat bahkan untuk proyek-proyek kecil, tetapi karena proyek tumbuh.
Tamás Szelei

6
@ Ikan: Saya setuju sebagian besar, decoupling sering merupakan ide yang baik, tetapi IMHO ada cukup situasi di mana menjaga hal-hal sederhana melebihi pendekatan multi-layer-super-decoupled-for-the-sake-of-decoupling. Bagian yang sulit adalah jangan sampai ketinggalan titik selama pertumbuhan suatu proyek ketika seseorang harus memulai refactoring.
Doc Brown

45

Apakah duplikasi kelas bermanfaat / desain bagus?

Praktik yang baik untuk memiliki kelas model tampilan terpisah untuk digunakan di lapisan UI daripada menggunakan kelas yang sama yang digunakan di lapisan data. Halaman UI / web Anda mungkin perlu menampilkan bit informasi lain yang tidak terkait erat dengan entitas data. Dengan membuat kelas tambahan ini, Anda memberi diri Anda kebebasan untuk mengubah UI Anda dengan mudah karena persyaratan berubah seiring waktu.

Sejauh menggunakan AutoMapper, saya pribadi menghindarinya karena 3 alasan:

Kegagalan diam lebih sering terjadi

Karena AutoMapper memetakan antara properti secara otomatis, mengubah nama properti di satu kelas dan bukan yang lain akan menyebabkan pemetaan properti dilewati. Kompiler tidak akan tahu. Automapper tidak akan peduli.

Kurangnya analisis statis

Jadi Anda telah diberi basis kode yang besar untuk dihadapi. Ada sejuta kelas dengan sejuta properti. Banyak yang terlihat seperti tidak digunakan, atau merupakan duplikat. Alat "Temukan semua referensi" di Visual Studio akan membantu Anda melihat di mana properti digunakan dan membantu membangun peta di kepala Anda tentang bagaimana seluruh aplikasi saling terkait. Tapi tunggu, tidak ada referensi eksplisit untuk setengah properti karena Automapper sedang digunakan. Pekerjaan saya sekarang jauh lebih sulit.

Persyaratan terlambat yang meningkatkan kompleksitas

Automapper baik-baik saja dan keren ketika semua yang ingin Anda lakukan adalah menyalin nilai dari satu kelas ke kelas lain (seperti yang sering terjadi pada MULAI pengembangan), tetapi ingat persyaratan yang berubah dari waktu ke waktu? Bagaimana jika sekarang Anda perlu mendapatkan nilai dari bagian lain aplikasi Anda, mungkin khusus untuk pengguna yang masuk atau keadaan kontekstual lainnya?

Pola AutoMapper untuk membuat pemetaan kelas satu-ke-satu pada awal aplikasi tidak cocok dengan perubahan-perubahan spesifik konteks semacam ini. Ya, mungkin ada cara untuk membuatnya bekerja, tetapi saya biasanya merasa lebih bersih, lebih sederhana dan lebih ekspresif untuk menulis logikanya sendiri.

Singkatnya, sebelum meraih Automapper untuk menghemat 30 detik pemetaan satu kelas secara manual, pikirkan hal ini.

Pemrograman adalah seni memberi tahu manusia lain apa yang diinginkan komputer. - Donald Knuth

Dengan mengingat hal ini, tanyakan pada diri Anda "apakah AutoMapper bermanfaat hari ini dan apakah akan besok?"


[jika Anda melakukan web dev yang trendi] Jadi, jika Anda menulis layanan web REST, apakah Anda cenderung selalu memeriksa setiap properti untuk memastikan model objek JavaScript Anda konsisten dengan model objek .NET Anda?
Den

3
@Den - ya. Dan Anda menulis tes untuk memastikan Anda mendapatkan semua properti yang benar (yaitu tes Anda akan menunjukkan setiap properti yang telah Anda tambahkan di 1 tempat yang tidak disebarkan ke tingkatan lainnya)
gbjbaanb

@ gbjbaanb Saya mungkin hanya akan menggunakan refleksi untuk melakukan validasi ini dengan cara yang umum. Mungkin jelajahi kemungkinan memperluas AutoMapper untuk menambahkan beberapa validasi. Pasti akan menghindari banyak tugas manual.
Den

Sepenuhnya Setuju dengan Anda dan berpikir hanya aplikasi yang sangat sederhana yang dapat menggunakan automapper, tetapi ketika segalanya menjadi lebih kompleks, kita perlu menulis konfigurasi baru untuk automapper lalu mengapa tidak menulisnya dalam helper atau layanan mapper manual.
ahmedsafan86

21

Dalam pengalaman saya, ketika seseorang mengeluh tentang 'terlalu banyak boilerplate' dan ingin menggunakan AutoMapper, itu salah satu dari yang berikut:

  1. Mereka merasa menjengkelkan untuk menulis kode yang sama berulang kali.
  2. Mereka malas dan tidak ingin menulis kode yang berarti Ax = Bx
  3. Mereka berada di bawah tekanan waktu terlalu banyak untuk benar-benar berpikir tentang apakah menulis Ax = Bx berulang kali adalah ide yang baik dan kemudian menulis kode yang baik untuk tugas tersebut.

Namun:

  1. Jika itu benar-benar tentang menghindari pengulangan, Anda dapat membuat objek atau metode untuk abstrak itu. Anda tidak memerlukan AutoMapper.
  2. Jika Anda malas, Anda akan malas dan tidak akan mempelajari cara kerja AutoMapper. Alih-alih, Anda akan mengadopsi pola 'pemrograman secara kebetulan' dan menulis kode mengerikan tempat Anda memasukkan logika bisnis dalam profil AutoMapper. Dalam hal ini, Anda harus mengubah sikap Anda terhadap pemrograman atau mencari hal lain untuk dilakukan sebagai profesi. Anda tidak memerlukan AutoMapper.
  3. Jika Anda berada di bawah tekanan waktu terlalu banyak, masalah Anda tidak ada hubungannya dengan pemrograman itu sendiri. Anda tidak memerlukan AutoMapper.

Jika Anda memilih bahasa yang diketik secara statis, maka manfaatkan bahasa tersebut. Jika Anda mencoba untuk mengelak dari kontrol dalam bahasa yang membantu mencegah kesalahan karena terlalu sering menggunakan refleksi dan API ajaib seperti AutoMapper, itu artinya Anda memilih bahasa yang tidak memuaskan untuk kebutuhan Anda.

Juga, hanya karena Microsoft menambahkan fitur ke C # tidak berarti mereka adalah permainan yang adil dalam setiap situasi atau mereka mendukung praktik terbaik. Refleksi dan kata kunci 'dinamis', misalnya, harus digunakan dalam kasus di mana Anda tidak dapat mencapai apa yang Anda butuhkan tanpa kata kunci tersebut. AutoMapper bukanlah solusi untuk setiap use case yang belum dapat dipecahkan tanpanya.

Jadi, apakah duplikasi kelas desain yang buruk? Belum tentu.

Apakah AutoMapper adalah ide yang buruk? Ya, tentu saja.

Penggunaan AutoMapper menunjukkan kekurangan sistemik dalam proyek. Jika Anda merasa membutuhkannya, berhentilah dan pikirkan desain Anda. Anda akan selalu menemukan desain yang lebih baik, lebih mudah dibaca, lebih dapat dirawat, dan lebih bebas bug.


1
Kata baik, khususnya 2.
Mardoxx

2
Saya tahu bahwa ini adalah utas yang sangat lama, tetapi saya harus tidak setuju dengan 1. Anda tidak dapat membuat metode untuk pemetaan abstrak. Anda dapat untuk 1 kelas, tetapi jika memiliki 2, Anda memerlukan 2 metode. 3 - 3 metode. Dengan AM ini adalah 1 baris kode - definisi pemetaan. Plus, saya benar-benar berjuang dengan sebuah skenario, di mana saya memiliki Daftar <BaseType> diisi dengan 10 subtipe DTO. Saat Anda ingin memetakannya, Anda perlu mengaktifkan tipe DAN metode untuk menyalin nilai bidang. Dan bagaimana jika salah satu bidang harus dipetakan secara terpisah? Jawaban Anda hanya baik jika Anda memiliki beberapa kelas sederhana. AutoMapper menang telak dalam skenario yang lebih kompleks.
user3512524

1
(batas char) Satu-satunya perangkap AM saya pikir adalah kemungkinan mengubah nama properti di satu kelas dan bukan di yang lain. Tapi sungguh, seberapa sering Anda melakukan itu setelah desain selesai? Dan Anda dapat menulis metode uji generik yang menggunakan refleksi dan membandingkan nama properti. Seperti semua alat, AM harus digunakan dengan benar - tidak secara membabi buta, tidak dalam semua situasi, saya setuju. Tetapi mengatakan "Anda tidak boleh menggunakannya" adalah salah.
user3512524

7

Ada masalah yang lebih dalam di sini: fakta bahwa C # dan Java bersikeras sebagian besar / semua jenis harus dapat dibedakan berdasarkan nama daripada struktur: misalnya class MyPoint2Ddan class YourPoint2Dmerupakan jenis yang terpisah bahkan jika mereka memiliki definisi yang sama persis. Ketika jenis yang Anda inginkan adalah "beberapa hal anonim dengan xbidang dan ybidang" (yaitu catatan ), Anda kurang beruntung. Jadi, ketika Anda ingin mengubah a YourPoint2Dmenjadi MyPoint2D, Anda memiliki tiga opsi:

  1. Tuliskan beberapa pelat baja yang membosankan, berulang-ulang, di sepanjang baris this.x = that.x; this.y = that.y
  2. Hasilkan kodenya entah bagaimana.
  3. Gunakan refleksi.

Pilihan 1 cukup mudah dalam dosis kecil tetapi dengan cepat menjadi tugas ketika jumlah jenis yang Anda butuhkan untuk memetakan besar.

Pilihan 2 kurang diinginkan karena sekarang Anda harus menambahkan langkah ekstra ke proses pembuatan untuk menghasilkan kode, dan pastikan seluruh tim mendapatkan memo itu. Dalam kasus terburuk Anda harus memutar generator kode atau sistem template Anda sendiri juga.

Itu membuat Anda berpikir. Anda bisa melakukannya sendiri, atau Anda bisa menggunakan AutoMapper.


3

Automapper adalah salah satu perpustakaan / alat di mana kaisar benar-benar berlarian telanjang. Ketika Anda melewati logo mewah, Anda menyadari itu tidak melakukan apa pun yang tidak dapat Anda lakukan secara manual dengan hasil yang jauh lebih baik.

Sementara saya tidak sepenuhnya yakin bagaimana ini mengisyaratkan anggota pemetaan otomatis, kemungkinan besar melibatkan logika runtime tambahan dan kemungkinan refleksi. Ini mungkin penalti kinerja yang signifikan dengan imbalan penghematan waktu. Pemetaan manual, di sisi lain, petunjuk dijalankan sebelum waktu kompilasi.

Dalam kasus di mana AutoMapper tidak memiliki petunjuk, Anda harus mengkonfigurasi pemetaan dengan kode dan mengatur flag. Jika Anda akan repot melakukan semua pengaturan dan kerja kode, Anda harus mempertanyakan berapa banyak penghematannya dibandingkan pemetaan manual.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.