ผู้ควบคุมควรรู้เกี่ยวกับมุมมองและรุ่นหรือไม่ หรือในทางกลับกัน?


13

ฉันกำลังพยายามทำความเข้าใจว่าฉันควรทำสิ่งนี้หรือไม่

item = Model()
screen = View()
brain = Controller(item, screen)

หรือนี่ ..

brain = Controller()
item = Model(brain)
screen = View(brain)

หรือนี่ ..

class Controller():
    def __init__(self):
        item = Model(self)
        screen = View(self)

หรืออย่างอื่นอย่างสิ้นเชิง?

คำตอบ:


18

สำหรับฉันตัวเลือกแรกนั้นสมเหตุสมผล งานของคอนโทรลเลอร์คือประสานงานระหว่างมุมมองและโมเดล จากมุมมองนั้นมันสมเหตุสมผลที่คอนโทรลเลอร์จะเป็นผู้ควบคุมการอ้างอิงถึงมุมมองและโมเดล

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


9

ModelและViewมีความเป็นอิสระของแต่ละอื่น ๆ

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

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

Viewควรใช้ HTML แม่แบบที่จะนำเสนอข้อมูลในลักษณะเฉพาะที่ไม่ใช่แหล่งข้อมูล ไม่ควรผูกกับสคีมาของฐานข้อมูลของคุณแน่น ในการแสดงหัวเรื่องของเอกสารคุณจะต้องให้เอาท์พุตดูเนื้อหาของตัวแปรเทมเพลตที่เรียกว่าdocument_titleและControllerรู้เฉพาะว่ามีการตั้งค่าตัวแปรอย่างไรและModelรู้เฉพาะสาเหตุที่เอกสารนั้นมีชื่อนั้น


1
ฉันชอบคำตอบของคุณเพราะมันเจลด้วยความเข้าใจโดยรวมของ MVC อย่างไรก็ตามมันไม่ได้ตอบคำถามสำคัญส่วนหนึ่งโดยเฉพาะส่วนใดของคณะสามที่มีการอ้างอิงถึงคนอื่น ๆ ? ความสับสนที่ฉันคิดว่าเกิดจากข้อเท็จจริงที่ว่าคุณอธิบายคือ Views คือ "เทมเพลตโง่ ๆ ที่มีรู" (กล่าวคือไม่มีการอ้างอิงถึง Controller แต่คอนโทรลเลอร์รู้ดีว่า Views และปลั๊กข้อมูลจาก Model เข้ามา) ในขณะเดียวกันสิ่งที่ฉันพบเห็นบ่อยๆคือ Views ควรส่งการกระทำของผู้ใช้ไปยังคอนโทรลเลอร์ Views ทำได้อย่างไรโดยไม่ต้องอ้างอิงกับ C
alnafie

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

3

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

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

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


+1 คำตอบที่ดี ฉันสามารถเข้าใจรูปแบบการเรียกกลับสำหรับแอปพลิเคชันเดสก์ท็อปในแง่ที่คลาสสิค เตือนฉันเกี่ยวกับ MFC เก่าจาก Microsoft
Reactgular

2

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

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

โมเดลรักษาโมเดลและรายการการสมัครสมาชิกและควรแจ้งมุมมองการเปลี่ยนแปลงที่เกี่ยวข้องผ่านการสมัครสมาชิก

นอกจากนี้ยังจำเป็นต้องมีกลไกในการสร้างมุมมองและตัวควบคุมใหม่ (เนื่องจากใน MVC คุณควรจะสามารถมีมุมมองที่เหมือนกันสองโมเดลขึ้นไป (ซึ่งอาจเป็นมุมมองเดียวกัน (จุด) หรือมุมมองอื่น (จุด) ตามหลักเหตุผลเราสามารถพิจารณาได้ว่าคอนโทรลเลอร์จำเป็นต้องดำเนินการหรือมีการเข้าถึงโรงงาน view & controller (pair) ซึ่งสามารถเป็นส่วนหนึ่งของคอนโทรลเลอร์หรือส่วนประกอบอื่น


-1 ไม่ต้องแจ้งModels สอบถามการเปลี่ยนแปลงแล้วแสดงผลเพื่อแสดงการเปลี่ยนแปลงเหล่านั้น ViewsControllersModelViews
Reactgular

4
@MathewFoscarini ใน MVC มุมมองจะสมัครรับข้อมูลการเปลี่ยนแปลงจากรุ่น ดูตัวอย่างเช่นwiki.squeak.org/squeak/598

ฉันคิดว่าเราไม่ได้พูดถึงความแตกต่างในกรอบ MVC ที่มีอยู่ Zend MVC, C # .NET และ CakePHP ไม่เชื่อมต่อแบบจำลองกับมุมมอง มุมมองในกรอบงานเหล่านั้นเป็นอิสระ ฉันไม่รู้ว่าคุณทำงานกับ MVC อะไร แต่ฉันเรียกมันว่าไม่ใช่แบบดั้งเดิม
Reactgular

6
@MathewFoscarini: นั่นคือกรอบงานเว็บทั้งหมดและแม้ว่าพวกเขาจะเรียกตัวเองว่า "MVC" พวกเขาไม่ได้ติดตามสถาปัตยกรรม MVC แบบดั้งเดิม
วินไคลน์

2
ฉันไม่แน่ใจว่า MVC ใด ๆ จะเป็น "ดั้งเดิม" มากกว่า Smalltalk MVC เนื่องจากเป็นรูปแบบแรกที่อธิบายรูปแบบ

1

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

เพื่อให้บรรลุสิ่งนี้รูปแบบคือการแยกตรรกะการใช้งานของแต่ละองค์ประกอบ MVC ยังคงเป็นปกติอย่างสมบูรณ์ว่ามีส่วนประกอบที่รู้จักกันคนอื่น ๆอินเตอร์เฟซ

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

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