มุมมองและโมเดลควรสื่อสารหรือไม่?


33

ตามหน้าวิกิพีเดียสำหรับสถาปัตยกรรม MVCมุมมองนั้นจะได้รับการแจ้งเตือนจากตัวแบบได้อย่างอิสระและยังมีอิสระในการสอบถามตัวแบบเกี่ยวกับสถานะปัจจุบันของมัน อย่างไรก็ตามตามหลักสูตรของ Paul Hegarty บน iOS 5 ที่ Stanford การบรรยายที่ 1 หน้า 18การโต้ตอบทั้งหมดจะต้องผ่านตัวควบคุมด้วย Model and View ที่ไม่ควรจะรู้จักกัน มันไม่ชัดเจนสำหรับฉันถ้าคำแถลงของ Hegarty จะต้องทำให้ง่ายขึ้นสำหรับหลักสูตร แต่ฉันอยากพูดว่าเขาตั้งใจออกแบบเช่นนี้

คุณจะอธิบายมุมมองตรงข้ามทั้งสองนี้ได้อย่างไร

คำตอบ:


26

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

หนึ่งในเป้าหมายหลักของ MVC / MVVM คือการแยก UI, ตรรกะทางธุรกิจและข้อมูลออก ดังนั้นด้วยแนวคิดที่อยู่ในใจการอนุญาตให้มุมมองเข้าถึงโมเดลโดยตรงสร้างการพึ่งพาที่คุณอาจไม่ต้องการ ในทางกลับกันการห่อแบบจำลองใน ViewModels มักจะน่าเบื่อและไม่มีประโยชน์มากเนื่องจาก ViewModels มักจะทำหน้าที่ส่งผ่านไปยังแบบจำลอง

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


1
ในส่วนที่เกี่ยวกับการทำแผนที่แบบจำลองที่น่าเบื่อกับมุมมองแบบจำลองนั้นควรสังเกตว่ามีเครื่องมือที่สามารถบรรเทาความเจ็บปวดในการทำแผนที่ได้ EG: (. NET AutoMapper) (JAVA modelmapper)
Jesse

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

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

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

12

บนเว็บทุกคนเรียก MVC decoupling ของพวกเขา

เทคโนโลยีบางอย่างเช่น C # ใช้ MVVM เนื่องจากไม่มีการเชื่อมโยงระหว่างมุมมองและอื่น ๆ ทุกอย่างต้องผ่านตัวระบุตำแหน่งบริการผูกตัวแปร

ใน MVC บริสุทธิ์ View จะพูดโดยตรงกับ Model และในทางกลับกัน คอนโทรลเลอร์จะมีก็ต่อเมื่อมีการเปลี่ยนแปลงเกิดขึ้น

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

คุณจะเห็นคำอธิบายที่ดีกว่าได้ที่นี่: http://www.garfieldtech.com/blog/mvc-vs-pac


7

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

เมื่อมุมมองใกล้ชิดเกินไปกับแบบจำลอง ViewModel อาจเป็นสิ่งที่สวยงาม แต่โดยทั่วไปแล้วสำหรับฉันแล้วกรณีที่เรียกได้ว่าเป็นของชนกลุ่มน้อย


6

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

กับคนที่แต่งตัวประหลาดในระหว่างการทำสื่อกลางรูปแบบควรจะเรียกว่าMVPและในความเป็นจริงสิ่งที่นำเสนอในปัจจุบันส่วนใหญ่เป็น MVC ในความเป็นจริงใกล้กับ MVP

จากนั้นมีMVVMซึ่งเป็นสิ่งที่คล้ายกับทั้งสองและแตกต่างกันเล็กน้อยและมีอยู่นานแล้ว ... ที่ดีที่สุดที่จะเห็นมันเป็นสอง MVCs / MVPs ผูกพันกันผ่านวัตถุ viewmodel - "ลูกค้า" MVC มี viewmodel เป็น โมเดลและ MVC "เซิร์ฟเวอร์" มี viewmodel เป็นมุมมอง


1
วันนี้ (ต้นปี 2014) สำหรับฉัน (กับโหนดและสแต็กเชิงมุมของฉัน) ความแตกต่างนี้ใน "ลูกค้า" MVC และ "เซิร์ฟเวอร์" MVC ดูเหมือนว่ามีความเกี่ยวข้องมากและอย่างใดก็ตรัสรู้ (ขอบคุณ)
slacktracer

4

เมื่อคุณถามเกี่ยวกับเนื้อหาในการบรรยายของ Stanford คุณควรพิจารณาสองสิ่งเกี่ยวกับท่าทางของ Hegarty:

  1. ดังที่คุณได้กล่าวไปแล้วเขากำลังสอนหลักสูตร Sci คอมพิวเตอร์ระดับ l00 มีสถานที่มากมายในการบรรยายของเขาที่เขาลดความซับซ้อนคัดสรรรายละเอียดหรือพูดว่า "ทำแบบนี้" อย่างที่ควรจะเป็นเมื่อต้องสอนพื้นฐานเช่นคุณต้องเชี่ยวชาญกฎก่อนจึงจะทำลายได้
  2. ประสบการณ์ของฉันกับ iOS SDK คือที่ ๆ มันไม่ได้บังคับแยกระหว่าง View และ Model อย่างเข้มงวดมันมุ่งเน้นไปที่รูปแบบนั้นอย่างมาก โดยเฉพาะอย่างยิ่งเมื่อเขียนแอพ iOS การปฏิบัติตามการแยกมุมมองแบบจำลองช่วยให้คุณเขียนโค้ดที่สอดคล้องกับความคาดหวังของเฟรมเวิร์ก ฉันลังเลที่จะพูดคุยกับ Hegarty เพื่อพัฒนาแพลตฟอร์มอื่น ๆ หรือโดยทั่วไป

1

ฉันเห็นด้วยกับ Paul Hegarty และเชื่อว่ามุมมองต้องไม่ทราบเกี่ยวกับแบบจำลอง ไม่ใช่เรื่องยากที่จะบรรลุ แต่นำประโยชน์เพิ่มเติมมาให้กับการออกแบบและความยืดหยุ่นในอนาคตของคุณ

ในแอปพลิเคชันขนาดเล็ก (โดยปกติเป็นเดสก์ท็อป) ที่ฉันต้องการหลีกเลี่ยงคลาส "จำลอง" และทำสิ่งต่าง ๆ ให้เรียบง่ายฉันยังใช้อินเทอร์เฟซ IModel (ดูคำตอบข้างต้น) และดูแลรุ่นที่ไม่มีความคิดเกี่ยวกับมุมมอง เช่นเดียวกับใน MVC แบบคลาสสิก)

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

วิธีที่สอง "ลดความซับซ้อน" นั้นใช้ได้เมื่อคุณอาจมีหลายมุมมองสำหรับรุ่นเดียวกัน แต่ฉันไม่แนะนำถ้าคุณต้องการใช้มุมมองเดียวกันสำหรับรุ่นที่แตกต่างกัน ภายใต้ที่แตกต่างกันฉันหมายถึงแตกต่างกันตามธรรมชาติและไม่ใช่แค่คลาสการทดสอบ JUnit ที่ "ติดตาม" โมเดลหลัก


1

ฉันเชื่อว่าไม่มีกฎที่ยากและรวดเร็วสำหรับสิ่งนี้มันขึ้นอยู่กับความต้องการของคุณ

คุณจะพบคนที่มีความเชื่อต่างกัน สถาปัตยกรรมเป็นแนวคิดที่จะช่วยออกแบบทางออกที่ดีกว่า

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

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

ดังนั้นคุณธรรมของเรื่องราวคือ MVC หมายถึงแบบจำลองมุมมองและตัวควบคุมควรแยกจากกัน นอกจากนั้นสิ่งที่เหมาะกับคุณที่สุด


0

ฉันใช้ DTO เพื่อการสื่อสารในรูปแบบมุมมอง

ตัวอย่างเช่น

  • ผู้ใช้กรอกฟอร์มอัปเดต (ดู)
  • ผู้ใช้ส่งแบบฟอร์ม
  • ตัวควบคุมผูกข้อมูลในฟอร์มไปยัง UserUpdateDTO
    • DTO และ UserModel เป็น POJOs แต่ DTO ไม่มี id และชื่อผู้ใช้เพราะเราไม่สามารถอัปเดตชื่อผู้ใช้
    • ความแตกต่างอีกอย่างคือคลาสโมเดลมีความสัมพันธ์และการเชื่อมโยง แต่ DTO เก็บข้อมูลเท่านั้นและเราอาจเพิ่มเครื่องมือตรวจสอบ JSR 303 ให้กับมัน
  • ผู้ควบคุมบอกว่ามันเป็นเลเยอร์บริการที่จะบันทึก
  • Service layer บอกกับ DAO layer เพื่อคงข้อมูลไว้

-1

ฉันอยู่กับค่ายที่บอกว่ามุมมองไม่ควรสื่อสารกับนางแบบ ตัวควบคุมจะต้องเป็นคนที่แต่งตัวประหลาดทุกสิ่งจากนั้นจะตัดสินใจว่าจะทำอย่างไร (ตรวจสอบความถูกต้องขอข้อมูลจากแบบจำลอง ฯลฯ )

ฉันมักจะเห็นว่ามันเป็นปัญหาขององค์กรมากกว่าสิ่งอื่นใด


-1

มีหลายคนที่แนะนำว่าทำไมและวิธีที่มุมมองและแบบจำลองควรมีการโต้ตอบอย่างอิสระในบริบทที่แตกต่างกัน แต่เหตุผลหลักใน iOS สำหรับการทำตัวควบคุมคือสื่อกลางระหว่างพวกเขาคือการหลีกเลี่ยงการพึ่งพา Model & View ในฐานรหัสของคุณ รุ่นหรือมุมมองตามความต้องการกับการพัฒนาของ iOS

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

แม้ว่าฉันยอมรับว่า MVC ใน iOS สร้าง ViewControllers ขนาดใหญ่ที่มีจำนวนมาก logics ในนั้นและจัดการทุกชนิดของสิ่งอื่น ๆ นอกเหนือจากที่ตั้งใจไว้ดังนั้นดีกว่าที่จะไปกับ MVVM หรือ Presentation Controls เพื่อทำให้รหัสของคุณยืดหยุ่นและง่ายขึ้น เพื่ออ่านและบำรุงรักษาได้ด้วย ViewControllers ที่เล็กลง

นี่อาจช่วยผู้ที่กำลังมองหา ViewControllers ที่เล็กลงใน iOS:

http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/

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