เป็นความคิดที่ดีที่จะเพิ่ม ViewModel เหมือนกับ Model


16

ฉันมีเลเยอร์ต่อไปนี้ในโซลูชันของฉัน:

  1. App.Domain
  2. App.Service
  3. App.Core (บางทีคุณอาจเรียกแอปนี้ว่า DataLayer)
  4. App.Web

รูปแบบการออกแบบซอฟต์แวร์ไม่ใช่คำถามของฉันฉันมี Model ต่อไปนี้ Domain

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

ฉันต้องการใช้โมเดลนี้ในมุมมอง (ตัวอย่างเช่นหน้าแรก) และฉันต้องการใช้Id, Name & Valueดังนั้นหากฉันต้องการสร้าง ViewModel ฉันจะเพิ่มสิ่งต่อไปนี้:

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

ดังนั้นความคิดที่ดีคืออะไร? หรือเพียงแค่ใช้FooแทนFooViewModel?


ฉันไม่แน่ใจว่าฉันเข้าใจสิ่งนี้ ไม่Modelส่งผ่านไปยังปกติViewหรือไม่ ว่าทำไมคุณต้องสร้างสาขาของModelในView? ถ้าแยกของความกังวลเป็นเป้าหมายของMVCภายใต้สถานการณ์สิ่งที่ใครอยากจะทำสิ่งเดียวกันกับ ModelและView? ถ้าViewModelเป็นทั้งคู่ทำไมไม่ขยาย / แต่งทั้งสองModelและView?
โมฆะ

โปรดอ่านความคิดเห็นของฉันเกี่ยวกับคำตอบของ @ svidgen
Mehdi Dehghani

ฉันมีปัญหาที่เกี่ยวข้อง - ที่การตรวจสอบ (แอตทริบิวต์ที่จำเป็น) ในรูปแบบ (และในฐานข้อมูล) ระบุค่าบางอย่าง - แต่ในมุมมองค่าเหล่านั้นไม่จำเป็นต้อง - ดังนั้นฉันถูกบังคับให้คัดลอกบางฟิลด์จาก โมเดลที่อยู่ภายในโมเดลของมุมมอง - แทนที่จะอ้างอิงโมเดลโดยตรง อย่างไรก็ตามจากการไตร่ตรองสิ่งนี้อาจเป็นเรื่องปกติและไม่ได้ละเมิด DRY เนื่องจากมีวัตถุประสงค์ที่แตกต่างกัน (ไม่มากเกินไป)
niico

คำตอบ:


20

สิ่งนี้อาจดูเหมือนละเมิดกฎ DRY ในขั้นต้น แต่ฉันยืนยันว่า "รหัสที่คล้ายกันและเหมือนกัน" ไม่จำเป็นต้อง "ซ้ำซ้อน" หากทำสิ่งที่แตกต่างออกไปหรือสามารถเปลี่ยนแปลงได้อย่างอิสระ และในกรณีของโมเดลการดูโค้ดจะกำหนดสิ่งที่ลูกค้าเห็นไม่จำเป็นต้องเป็นเอนทิตีและการดำเนินการที่ธุรกิจพูดถึง ดังนั้นคุณมักจะเปิดเผยโมเดลให้กับลูกค้าหรืออินเทอร์เฟซที่เป็นแบบ "บังเอิญเหมือนกัน" คุณสามารถเปลี่ยนแปลงกฎและข้อกำหนดทางธุรกิจหรือคำศัพท์เฉพาะของผู้ใช้ซึ่งเป็นอิสระจากกัน

ดังนั้นฉันจะหันกลับไปถามคุณ หากการเปลี่ยนแปลงโดเมนเป็นที่ยอมรับหรือไม่สำหรับลูกค้า "รุ่น 1" เพื่อใช้อินเทอร์เฟซเก่าต่อไป คุณจะเปิดเผยคำหรือการดำเนินการในอินเทอร์เฟซที่ไม่ได้เป็นส่วนหนึ่งของ "กฎธุรกิจหลักหรือไม่" และในทางกลับกัน?

คำถามเหล่านี้อยู่ในใจหากฟังก์ชั่น "มุมมอง" ของคุณนั้นเปิดเผยโมเดลโดเมนพื้นฐานอย่างเคร่งครัดใช่ดูเหมือนว่าจะเป็นการละเมิดกฎ DRY

โปรดจำไว้ว่าการเปิดเผยมุมมองที่เปลี่ยนแปลงอย่างเป็นธรรมชาติยิ่งขึ้นด้วยการเปลี่ยนแปลงแบบจำลองสามารถทำได้ในบางภาษาด้วยคุณลักษณะของสมาชิกและการสะท้อนกลับ (หรือน้อยกว่าด้วยทำซ้ำผ่านความสำเร็จอื่น ๆ ของความฉลาด ... แต่ "ความฉลาด" มักจะล้มเหลวในการพิสูจน์การทำซ้ำมันอะไหล่คุณ)


โน้ตที่กล่าวถึงเป็นอย่างดี (โหวตขึ้นเพื่อสิ่งนี้) ตามที่ฉันพูดเป็นความคิดเห็นในคำตอบก่อนหน้าฉันกำลังพูดถึงวัตถุประสงค์ทั่วไปการถ่ายภาพบางทีหลายวันต่อมาฉันตัดสินใจที่จะเพิ่มฟิลด์ / ทรัพย์สินFooใหม่ให้ดังนั้นถ้าฉันใช้Fooเป็น ViewModel ลูกค้าก็จะได้รับคุณสมบัติใหม่ด้วยดังนั้นถ้าใหม่นี้เป็นเขตรักษาความปลอดภัย (อาจเป็นจริง / เท็จเพื่อขออนุญาตหรืออะไรทำนองนั้น) ฉันควรทำอย่างไร
Mehdi Dehghani

@mehdi คุณจะต้องเจาะจงมากขึ้นเกี่ยวกับฟิลด์ที่คุณต้องการเพิ่มและทำไมคุณคิดว่ามันเป็นหรือไม่อยู่ในมุมมอง หรือโดยทั่วไปสิ่งที่กังวลอยู่ที่นั่น
svidgen

@mehdi ชัดเจนว่าถ้าคุณกังวลเกี่ยวกับผู้ใช้ปลายทางที่เปลี่ยนค่าความปลอดภัยโดเมนของคุณก็ไม่ควรอนุญาตให้ผู้ใช้บันทึกสิ่งที่ไม่ได้รับอนุญาตให้บันทึก
svidgen

ทำไมเราใช้ ViewModels มีเหตุผลบางอย่างที่เรารู้หนึ่งในนั้นคือเพื่อความปลอดภัยตัวอย่างเช่นในUser edit formเราไม่จำเป็นต้องส่งIsAdminฟิลด์ไปยังลูกค้าเพื่อรักษาความปลอดภัยของฟิลด์นี้ดังนั้นนี่คือสิ่งที่ฉันกังวล ขอโทษสำหรับภาษาอังกฤษที่ไม่ดีของฉัน
Mehdi Dehghani

1
อีกวิธีหนึ่งฉันคิดว่าคำถามเดิมเป็นคำถามแบบเต็ม คำถามที่คุณพยายามค้นหาในความคิดเห็นที่นี่เป็นอีกคำถามหนึ่ง และความคิดเห็นไม่ใช่วิธีที่ดีในการรับคำตอบที่ดีและมีคุณภาพ
svidgen

2

ฉันจะมีรูปแบบการดูที่มีเพียงหนึ่งคุณสมบัติเช่นอินสแตนฟู ด้วยวิธีนี้คุณจะไม่ละเมิด DRY ตามคำจำกัดความใด ๆ ของมันหาก Foo เปลี่ยนแปลงโมเดลมุมมองของคุณจะเห็นการเปลี่ยนแปลงโดยอัตโนมัติและคุณปล่อยให้คุณเป็นอิสระจากโมเดลมุมมองโดยตรงกับโมเดล

หากวันพรุ่งนี้มีความต้องการมุมมองที่จะแสดงอย่างอื่นเช่นเดียวกับ Foo คุณสามารถเพิ่มคุณสมบัติใหม่และความตั้งใจของรูปแบบการดูของคุณจะยังคงชัดเจนมันมี Foo และอย่างอื่นคุณจะไม่มี ส่วนผสมของคุณสมบัติจาก Foo กับคุณสมบัติอื่น ๆ ที่ไม่เกี่ยวข้อง

ฉันไม่คิดว่ารูปแบบการดูของคุณเป็น FooViewModel ฉันจะคิดในแง่ของมุมมองที่ควรแสดง หากมันแสดงเพียงหนึ่ง Foo โมเดลการดูจะมีหนึ่งคุณสมบัติคือ Foo

ไม่แน่ใจว่าฉันอธิบายอย่างชัดเจนหรือไม่ ถ้าไม่บอกให้ฉันรู้แล้วฉันจะพยายามและพูดมันอีกครั้งเมื่อฉันตื่น!


-2

ฉันจะบอกว่าการใช้FooViewModelวิธีนี้เป็นการละเมิดครูใหญ่ เมื่อคุณต้องการเปลี่ยนแปลงFooคุณต้องทำการเปลี่ยนแปลงFooViewModelด้วย ฉันคิดว่าคุณน่าจะได้รับบริการที่ดีกว่าเพียงใช้Fooเป็นโมเดลสำหรับมุมมองของคุณ ฉันจะพิจารณาโมเดลการดูหากคุณต้องการแสดงสิ่งต่าง ๆ จาก Foo และอย่างอื่น ตัวอย่างเช่นสมมติว่าคุณต้องการที่จะทำให้ข้อมูลบางอย่างจากและจากFooBar


โปรดบอกฉันว่าถ้าฉันตัดสินใจที่จะเพิ่มเขตข้อมูล / ทรัพย์สินอื่นไปที่Fooดังนั้นเนื่องจากฉันใช้Fooเป็น ViewModel ด้วยดังนั้นฉันต้องผ่านเขตข้อมูลใหม่นี้ไปยังมุมมองด้วยฉันคิดว่านี่ไม่ใช่ข้อตกลงที่ดีจริงๆคุณคิดอย่างไร ?
Mehdi Dehghani

ฉันไม่เห็นอะไรผิดปกติกับการใช้มุมมองใช้ชุดย่อยของข้อมูลที่เปิดเผยโดยตัวแบบ ผมคิดว่าเหม็นมากขึ้นคือการมีเพศสัมพันธ์ระหว่างและFoo FooViewModelโดยทั่วไปไม่ควรแก้ไขไฟล์หลาย ๆ ไฟล์สำหรับการเปลี่ยนแปลงแบบลอจิคัลเดียว
zero_dev

ถ้าฟิลด์ที่เพิ่มนั้นเป็นฟิลด์ความปลอดภัยเช่นtrue/falseค่าอนุญาตหรือบางอย่างเช่นนั้น
Mehdi Dehghani

คุณไม่ต้องเปิดเผยฟิลด์ดังกล่าวในมุมมองตัวเอง แต่คุณควรตรวจสอบให้แน่ใจว่าส่วนที่เหลือของรหัสของคุณไม่อนุญาตให้ผู้ใช้เปลี่ยนระดับความปลอดภัยของพวกเขาในกรณีที่ผู้ใช้ที่ประสงค์ร้ายพยายามโพสต์การเปลี่ยนแปลงดังกล่าว
เกรแฮม

ฟังดูเหมือนว่าจะเปิดให้โจมตีแบบมอบหมายจำนวนมาก
James
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.