Apakah itu ide yang baik untuk menambahkan ViewModel persis sama dengan Model

16

Saya memiliki lapisan berikut dalam solusi saya:

  1. App.Domain
  2. Aplikasi. Layanan
  3. App.Core (mungkin Anda menyebutnya App.DataLayer yang satu ini)
  4. Aplikasi.Web

Pola desain perangkat lunak bukan pertanyaan saya, saya telah mengikuti Model di Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Saya ingin menggunakan model ini pada tampilan (misalnya beranda) DAN saya ingin menggunakan Id, Name & Value, jadi jika saya ingin membuat ViewModel, saya akan menambahkan yang berikut:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Jadi, apakah itu ide yang bagus? atau hanya gunakan Foosaja FooViewModel?

Mehdi Dehghani
sumber
Saya tidak yakin saya mengerti ini. Bukankah Modelbiasanya dilewatkan ke View? Mengapa Anda perlu membuat ulang bidang Modeldi View? Jika pemisahan kekhawatiran adalah tujuan MVC, dalam keadaan apa seseorang ingin melakukan hal yang sama dengan Modeldan View? Jika ViewModelkeduanya, mengapa tidak dengan memperluas / menyusun keduanya Modeldan View?
null
tolong baca komentar saya pada jawaban @ svidgen
Mehdi Dehghani
Saya memiliki masalah terkait - di mana validasi (atribut yang diperlukan) pada model (dan dalam database) menyatakan nilai-nilai tertentu harus dimasukkan - tetapi dalam pandangan, nilai-nilai itu tidak perlu - jadi saya terpaksa menyalin beberapa bidang dari model ke model tampilan - daripada merujuk model secara langsung. Namun pada refleksi ini mungkin baik-baik saja dan memang tidak melanggar KERING karena mereka untuk tujuan yang berbeda (toh tidak terlalu buruk pula).
niico

Jawaban:

20

Ini mungkin terlihat seperti pelanggaran aturan KERING pada awalnya, tetapi saya berpendapat bahwa "kode yang serupa dan bahkan identik" tidak harus berarti "pengulangan" jika ia melakukan sesuatu yang berbeda atau dapat berubah secara independen. Dan dalam kasus model tampilan, kode mendefinisikan apa yang dilihat "klien", belum tentu entitas dan operasi yang dibicarakan bisnis. Jadi, Anda sering mengungkapkan model ke klien atau antarmuka yang agak "identik secara kebetulan." Anda dapat mengubah aturan dan ketentuan bisnis atau terminologi pengguna akhir secara independen satu sama lain.

Jadi, saya balikkan pertanyaannya pada Anda. Jika domain berubah, apakah klien "versi 1" dapat terus menggunakan antarmuka lama? Apakah Anda akan mengungkapkan istilah atau operasi di antarmuka yang bukan bagian dari "aturan bisnis inti?" Dan sebaliknya?

Pertanyaan-pertanyaan semacam itu ada dalam pikiran, jika "fungsi" tampilan Anda hanya untuk mengungkapkan model domain yang mendasarinya, ya, sepertinya ini melanggar aturan KERING.

Juga ingat, mengungkap pandangan bahwa perubahan lebih alami dengan perubahan model juga dapat dicapai dalam beberapa bahasa dengan atribut dan refleksi anggota. (Atau dengan pengulangan yang kurang melalui prestasi kepintaran lainnya ... Tapi, "kepintaran" sering gagal untuk membenarkan pengulangan yang membuat Anda terhindar.)

svidgen
sumber
Catatan yang bagus (pilih ini), seperti yang saya katakan sebagai komentar pada jawaban sebelumnya, saya sedang berbicara tentang tujuan umum, pencitraan, mungkin beberapa hari kemudian, saya memutuskan untuk menambahkan bidang / properti baru Foo, jadi jika saya digunakan Foosebagai ViewModel juga, klien akan mendapatkan properti baru juga, jadi bagaimana jika yang baru ini adalah bidang keamanan, (mungkin benar / salah untuk izin, atau sesuatu seperti itu), apa yang harus saya lakukan?
Mehdi Dehghani
@ mehdi Anda harus lebih spesifik tentang bidang apa yang ingin Anda tambahkan dan mengapa menurut Anda itu termasuk atau tidak termasuk dalam tampilan. Atau secara umum, apa yang menjadi perhatian.
svidgen
@mehdi menjadi jelas, jika Anda khawatir tentang pengguna akhir mengubah nilai keamanan, domain Anda seharusnya tidak memungkinkan pengguna untuk menyimpan hal-hal yang tidak diizinkan untuk disimpan
svidgen
Mengapa kami menggunakan ViewModels? ada beberapa alasan, seperti yang kita tahu, salah satunya adalah untuk keamanan, misalnya, User edit formkita tidak perlu meneruskan IsAdminbidang ke klien, untuk menjaga bidang ini tetap aman, jadi ini yang saya khawatirkan. maaf untuk bahasa inggris saya yang buruk.
Mehdi Dehghani
1
Dengan kata lain, saya pikir pertanyaan aslinya adalah pertanyaan penuh. Pertanyaan yang Anda coba cari dalam komentar di sini adalah pertanyaan lengkap lainnya. Dan komentar bukanlah cara yang baik untuk mendapatkan jawaban yang baik dan berkualitas.
svidgen
2

Saya akan memiliki model tampilan yang berisi hanya satu properti, contoh Foo. Dengan begitu, Anda tidak melanggar KERING menurut definisi apa pun, jika Foo berubah, model tampilan Anda secara otomatis melihat perubahan, dan Anda membiarkan diri Anda bebas dari ikatan langsung model tampilan dengan model.

Jika besok ada kebutuhan untuk tampilan untuk menunjukkan sesuatu yang lain serta Foo, Anda bisa menambahkan properti baru, dan maksud model tampilan Anda akan tetap jelas, itu berisi Foo dan sesuatu yang lain, Anda tidak akan memiliki campuran properti dari Foo dengan properti lain yang tidak terkait.

Saya tidak akan menganggap model tampilan Anda sebagai FooViewModel, saya akan memikirkannya dalam hal tampilan yang seharusnya ditampilkan. Jika hanya menampilkan satu Foo, maka model tampilan berisi satu properti, Foo.

Tidak yakin apakah saya menjelaskannya dengan jelas. Jika tidak, beri tahu saya dan saya akan mencoba dan menulis ulang ketika saya bangun!

Avrohom Yisroel
sumber
-2

Saya akan mengatakan menggunakan FooViewModelcara ini melanggar prinsip KERING. Ketika Anda perlu melakukan perubahan, FooAnda juga harus melakukan perubahan FooViewModel. Saya pikir Anda akan lebih baik dilayani hanya menggunakan Foosebagai model untuk pandangan Anda. Saya akan mempertimbangkan model tampilan jika Anda perlu menampilkan sesuatu dari Foo dan sesuatu hal lainnya. Misalnya, Anda perlu merender beberapa informasi dari Foodan juga dari Bar.

zero_dev
sumber
Tolong beritahu saya, jika saya memutuskan untuk menambahkan bidang / properti lain ke Foo, jadi karena saya juga digunakan Foosebagai ViewModel, jadi saya harus meneruskan bidang baru ini ke tampilan juga, saya pikir ini bukan kesepakatan yang bagus, bagaimana menurut Anda ?
Mehdi Dehghani
Saya tidak melihat ada yang salah dengan memiliki View hanya menggunakan sebagian dari data yang diekspos oleh model. Saya pikir pelanggaran yang lebih besar adalah hubungan antara Foodan FooViewModel. Secara umum, itu bukan ide yang baik untuk harus memodifikasi banyak file untuk satu perubahan logis.
zero_dev
Bagaimana dengan jika bidang yang ditambahkan itu adalah bidang keamanan, seperti beberapa true/falsenilai untuk izin atau sesuatu seperti itu.
Mehdi Dehghani
Anda tidak harus mengekspos bidang tersebut di tampilan itu sendiri, tetapi Anda harus tetap memastikan bahwa sisa kode Anda tidak memungkinkan pengguna untuk mengubah tingkat keamanan mereka, kalau-kalau pengguna jahat mencoba untuk POST perubahan seperti itu.
Graham
Kedengarannya seperti itu akan terbuka untuk serangan penugasan massal
James