DTO = ViewModel?


103

ฉันใช้ NHibernate เพื่อคงวัตถุโดเมนของฉัน เพื่อให้สิ่งต่างๆง่ายขึ้นฉันใช้โครงการ ASP.NET MVC เป็นทั้งเลเยอร์การนำเสนอและเลเยอร์บริการของฉัน

ฉันต้องการส่งคืนอ็อบเจ็กต์โดเมนของฉันใน XML จากคลาสคอนโทรลเลอร์ของฉัน หลังจากอ่านโพสต์บางส่วนที่นี่ใน Stack Overflow ฉันรวบรวม DTO เป็นวิธีที่จะไป อย่างไรก็ตามฉันยังเจอโพสต์ที่พูดถึง ViewModel

คำถามของฉัน: Data Transfer Objects และ ViewModels เป็นสิ่งเดียวกันหรือไม่ หรือ ViewModel เป็นรูปแบบย่อยของ DTO หรือไม่?


9
ฉันคิดว่ามันเกี่ยวข้องกับการพูดถึงว่า ViewModels ใน ASP.NET MVC ไม่เทียบเท่ากับ ViewModels ใน WPF (MVVM) 100% เนื่องจากคำตอบส่วนใหญ่พูดถึง MVVM และคุณกำลังทำงานกับ ASP.NET MVC
Matthijs Wessels

คำตอบ:


106

คำจำกัดความตามมาตรฐานของ DTO คือรูปร่างข้อมูลของวัตถุที่ไม่มีพฤติกรรมใด ๆ

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

อย่างไรก็ตามการคาดการณ์ของ NHibernate มีประโยชน์หากโมเดลมุมมองบางอย่างต้องการข้อมูลส่วนย่อยจากวัตถุที่ยังคงอยู่


คุณสามารถอธิบายสิ่งนี้ได้: "DTO คือรูปร่างข้อมูลของวัตถุที่ไม่มีพฤติกรรมใด ๆ "?
roozbeh S

2
ความหมาย ... คลาส DTO มักจะมีเฉพาะคุณสมบัติและไม่มีเมธอดใด ๆ ที่มีตรรกะทางธุรกิจ ฯลฯ ...
Daniel Auger

71

ViewModel ใน ASP.NET MVC นั้นเหมือนกับ DTO อย่างไรก็ตาม ViewModel ในรูปแบบ MVVM นั้นแตกต่างจาก DTO เนื่องจาก ViewModel ใน MVVM มีพฤติกรรม แต่ DTO ไม่มี


4
นี่เป็นคำตอบที่ดี แม้ว่าจะมีรายละเอียดสั้น ๆ
ฟิล

5
ทำไม ViewModel ใน asp.net mvc จึงเหมือนกับ DTO? นั่นไม่สมเหตุสมผล ViewModel สามารถมีลักษณะการทำงานที่ DTO ไม่ได้ สิ่งนี้ไม่ได้ขึ้นอยู่กับ mvc
Elisabeth

8
+1 สำหรับความแตกต่างระหว่าง ASP.NET MVC ViewModel และ MVVM ViewModel
Ronald

5
@Elisa - คำตอบสำหรับคำถามที่ค่อนข้างเก่าของคุณคือใน ASP.NET MVC มุมมองจะเรียกใช้ Actions บนคอนโทรลเลอร์ (ไม่ใช่ ViewModel) เพื่อเปลี่ยน Model และ View ในลักษณะไร้สถานะ ด้วยเหตุนี้ DTO ที่มีรูปร่างเป็นมุมมองจึงเหมือนกับ ViewModel เป็นหลัก อย่างไรก็ตามในระบบขนาดใหญ่ที่มีขอบเขตการทำให้เป็นอนุกรมอื่น DTO อาจเป็นประโยชน์หากแยกออกจาก ViewModel ที่มีรูปร่างเฉพาะสำหรับ View
dansan

27

DTO! = ViewModel

ในรูปแบบMVVM ViewModel ถูกใช้เพื่อแยก Model ออกจาก View ในการแสดงโมเดลคุณสามารถใช้คลาสDTOแบบง่ายซึ่งจะถูกแมปกับฐานข้อมูลอีกครั้งผ่านเช่น NHibernate แต่ฉันไม่เคยเห็นคลาส ViewModel ที่จำลองเป็น DTO .. ​​คลาส ViewModel ส่วนใหญ่มีพฤติกรรมซึ่ง DTO ไม่มี


2
ดังนั้น DTO จึงเป็นเพียงโครงสร้าง (หรือเป็นคลาสที่ควรเลียนแบบความสามารถของโครงสร้าง)
Max Alexander

20

DTO - ออบเจ็กต์การถ่ายโอนข้อมูลเป็นไปตามที่กล่าวไว้คือคอนเทนเนอร์สำหรับถ่ายโอนข้อมูล พวกเขาไม่มีพฤติกรรมใด ๆ แต่เป็นเพียงกลุ่มเซ็ตเตอร์และตัวรับ บางคนทำให้ไม่เปลี่ยนรูปและสร้างใหม่เมื่อจำเป็นแทนที่จะอัปเดตสิ่งที่มีอยู่ ควรต่ออนุกรมกันเพื่อให้สามารถโอนข้ามสายได้

โดยทั่วไป DTO จะใช้ในการจัดส่งข้อมูลจากเลเยอร์หนึ่งไปยังอีกเลเยอร์หนึ่งข้ามขอบเขตของกระบวนการเนื่องจากการโทรไปยังบริการระยะไกลอาจมีราคาแพงดังนั้นข้อมูลที่ต้องการทั้งหมดจะถูกผลักเข้าไปใน DTO และโอนไปยังไคลเอนต์เป็นกลุ่มเดียว (เม็ดหยาบ)

อย่างไรก็ตามบางคนใช้แนวคิดของ DTO ที่มีขอบเขตหน้าจอ (ไม่เกี่ยวข้องกับการข้ามขอบเขตของกระบวนการ) อีกครั้งเหล่านี้จะถูกเติมด้วยข้อมูลที่ต้องการ (โดยทั่วไปข้อมูลที่จำเป็นสำหรับหน้าจอหนึ่ง ๆ และอาจเป็นการรวมข้อมูลจากแหล่งต่างๆ) และส่งไปยังไคลเอนต์

http://blog.jpboodhoo.com/CommentView,guid,21fe23e7-e42c-48d8-8871-86e65bcc9a50.aspx

ในกรณีง่ายๆตามที่ได้ระบุไว้แล้ว DTO นี้สามารถใช้เพื่อเชื่อมโยงกับมุมมอง แต่ในกรณีที่ซับซ้อนกว่านั้นจะต้องมีการสร้าง ViewModel และการขนถ่ายข้อมูลจาก DTO ไปยัง ViewModel ซึ่งเห็นได้ชัดว่าทำงานได้มากกว่า (เมื่อใช้รูปแบบ MVVM) .

อีกครั้งตามที่ระบุไว้แล้ว DTO! = ViewModel

และ

DTO และ ViewModel มีจุดประสงค์ในชีวิตที่แตกต่างกัน


13

ประการแรกความแตกต่างที่สำคัญคือ ViewModel สามารถมีพฤติกรรมหรือวิธีการที่ DTO ต้องไม่ !!!

ประการที่สองการใช้ DTO เป็น ViewModel ใน ASP.NET MVC ทำให้แอปพลิเคชันของคุณเชื่อมโยงกับ DTO อย่างแน่นหนาและนั่นคือจุดประสงค์ที่ตรงกันข้ามกับการใช้ DTO ถ้าคุณทำเช่นนั้นความแตกต่างในการใช้โมเดลโดเมนหรือ DTO ของคุณมีความซับซ้อนมากขึ้นในการรับรูปแบบการต่อต้านอย่างไร

ViewModel ใน ASP.NET ยังสามารถใช้ DataAnnotations สำหรับการตรวจสอบความถูกต้อง

DTO เดียวกันสามารถมี ViewModels Mapping ที่แตกต่างกันและ One ViewModel สามารถประกอบจาก DTO ที่แตกต่างกันได้ (โดยไม่จัดองค์ประกอบการทำแผนที่วัตถุเสมอ) เพราะฉันคิดว่ามันจะแย่กว่านั้นถ้าคุณมี ViewModel ที่มี DTO เราก็จะมีปัญหาเดียวกัน

จากเลเยอร์การนำเสนอของคุณให้นึกถึง DTO เป็นสัญญาคุณจะได้รับวัตถุที่คุณต้องพิจารณาว่าเป็นคนแปลกหน้าสำหรับแอปพลิเคชันของคุณและไม่มีการควบคุมใด ๆ (แม้ว่าคุณจะมีอดีตบริการ dto และเลเยอร์การนำเสนอก็ตาม เป็นของคุณ)

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


1
ฉันเพิ่งติดตั้ง VS 2012 และดูที่นั่น MVC 4 Single Page Application ในโครงการตัวอย่าง DTO ถูกใช้เป็นพารามิเตอร์สำหรับวิธีการควบคุม (หรือการดำเนินการ) ใน WebApi กล่าวอีกนัยหนึ่ง JSON ถูกโพสต์ไปยังวิธีการเหล่านั้นและด้วยเวทมนตร์ MVC ข้อมูลจะถูกแปลงเป็น DTO โดยอัตโนมัติก่อนที่จะส่งต่อไปยังวิธีการ คุณคิดว่าการใช้ DTO ในกรณีนี้ผิดหรือไม่ ควรใช้ ViewModels กับ Web API หรือไม่ ฉันขอให้เข้าใจดีขึ้นเพราะฉันยังไม่คุ้นเคยกับแนวคิดเหล่านี้ทั้งหมด
Jean-François Beauchamp

Salut Jean-François Beauchamp :) ASP.NET MVC สามารถแยกวิเคราะห์ url prams ลงในออบเจ็กต์ได้เช่นสมมติว่าฉันมีการแมปนี้กับเมธอด Index ajax / index / {jobID} / {ResultsToSkip} / {ResultsToSend} "แทนที่จะมี ในดัชนี controlle (int jobID, int ResultsToSkip, int ResultsToSend) ฉันจะมีดัชนี (คำขอ) (คำขอคือวัตถุที่ห่อหุ้ม 3 ฟิลด์ jobID ... DATA ใช่เราสามารถพูด requestDTO ได้ตัวอย่างเช่นคุณต้องเพิ่มอีกหนึ่งฟิลด์ที่คุณเปลี่ยนเฉพาะ DTO ไม่ใช่วิธีการเชื่อมต่อ api
riadh gomri

9

สำหรับมุมมองที่เรียบง่ายฉันจะใช้ DTO เป็นโมเดลของฉัน แต่เมื่อ Views ซับซ้อนขึ้นฉันจะสร้าง ViewModels

สำหรับฉันมันคือความสมดุลระหว่างความรวดเร็ว (โดยใช้ DTO เนื่องจากฉันมีพวกเขาอยู่แล้ว) และความยืดหยุ่น (การสร้าง ViewModels หมายถึงการแยกความกังวลมากขึ้น)


2
คำตอบที่ดีในทางปฏิบัติ
Simon Tewsi

0

หากคุณจะใช้ DTO เป็น ViewModel นั่นหมายความว่าคุณมีการพึ่งพา DTO สูงเนื่องจากเหตุผลบางประการที่คุณเปลี่ยน DTO อาจส่งผลกระทบต่อ ViewModel

ใช้ DTO และแปลงเป็น viewmodel ได้ดีขึ้น


-1

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

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