อะไรคือ“ ตัวควบคุม” ใน“ MVC”


186

ฉันคิดว่าฉันเข้าใจแนวคิดพื้นฐานของ MVC - ตัวแบบมีข้อมูลและพฤติกรรมของแอปพลิเคชันมุมมองมีหน้าที่รับผิดชอบในการแสดงให้ผู้ใช้และตัวควบคุมจัดการกับอินพุตของผู้ใช้ สิ่งที่ฉันไม่แน่ใจคือสิ่งที่เกิดขึ้นในคอนโทรลเลอร์

ให้พูดเช่นฉันมีแอพพลิเคชั่นที่ค่อนข้างเรียบง่าย (ฉันกำลังคิดถึง Java เป็นพิเศษ แต่ฉันคิดว่าหลักการเดียวกันนี้ใช้กับที่อื่น) ผมจัดระเบียบรหัสของฉันเป็น 3 แพคเกจที่เรียกว่าapp.model, และapp.viewapp.controller

ภายในapp.modelแพ็คเกจฉันมีคลาสไม่กี่คลาสที่สะท้อนถึงพฤติกรรมที่แท้จริงของแอปพลิเคชัน สิ่งเหล่านี้extends Observableและใช้setChanged()และnotifyObservers()เพื่อทริกเกอร์มุมมองเพื่ออัพเดตเมื่อเหมาะสม

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

แล้วฉันจะใส่อะไรในคอนโทรลเลอร์? ฉันใส่public void actionPerformed(ActionEvent e)ในมุมมองด้วยการโทรไปยังวิธีการในคอนโทรลเลอร์หรือไม่ ถ้าเป็นเช่นนั้นควรมีการตรวจสอบความถูกต้อง ฯลฯ ในคอนโทรลเลอร์หรือไม่? ถ้าเป็นเช่นนั้นฉันจะส่งข้อความแสดงข้อผิดพลาดกลับไปยังมุมมองได้อย่างไร - ควรผ่านโมเดลอีกครั้งหรือผู้ควบคุมควรส่งตรงไปที่มุมมอง

หากการตรวจสอบเสร็จสิ้นในมุมมองฉันจะใส่อะไรลงในคอนโทรลเลอร์

ขออภัยสำหรับคำถามที่ยาวฉันแค่ต้องการเอกสารความเข้าใจของฉันเกี่ยวกับกระบวนการและหวังว่าใครบางคนสามารถชี้แจงปัญหานี้ให้ฉัน!

คำตอบ:


520

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

ในรูปแบบการสนทนา:

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

ในตอนท้ายของส่วนนั้นคุณมีตัวเลือก: มุมมองสามารถทำการร้องขอแยกต่างหาก "ให้ชุดข้อมูลล่าสุดกับฉัน" และทำให้บริสุทธิ์ยิ่งขึ้นหรือตัวควบคุมส่งคืนชุดข้อมูลใหม่ด้วย "ลบ" "การดำเนินการ


90
บทสนทนานั้นเป็นคำอธิบายที่ดีที่สุดของ MVC ฉันเจอแล้วขอบคุณ!
Paul Walker

13
ทุกอย่างดี แต่ไม่มีอะไรผิดปกติกับการอ่านมุมมองจากโมเดลโดยตรง "ผู้ควบคุมไม่ใช่ตำรวจข้อมูล" นอกจากนี้ยังมีหลักคำสอนที่บอกว่าให้ควบคุมบาง View Helpers เป็นสถานที่ที่สมบูรณ์แบบในการรวบรวมข้อมูลที่พร้อมใช้งานในมุมมองของคุณ หนึ่งไม่ควรส่งตัวควบคุมที่สมบูรณ์สแต็คเพื่อใช้ตรรกะการเข้าถึงข้อมูลบางส่วน รายละเอียดเพิ่มเติม: rmauger.co.uk/2009/03/…
ข้อยกเว้น e

1
ฉันเห็นด้วยกับ "ข้อยกเว้น e" ข้อมูลในโมเดลสามารถอัปเดตได้โดยเหตุการณ์มากมายไม่จำเป็นต้องเป็นคอนโทรลเลอร์และดังนั้นใน MVC บางตัวจึงออกแบบ M ให้สัญญาณ V ว่าข้อมูลสกปรกและ V สามารถรีเฟรชตัวเองได้ C ไม่มีบทบาทในกรณีนั้น
Mishax

68

ปัญหาMVCคือคนคิดมุมมองตัวควบคุมและรูปแบบจะต้องมีความเป็นอิสระมากที่สุดจากกัน พวกเขาไม่ได้ - มุมมองและควบคุมมักจะพัน - M(VC)คิดว่ามันเป็น

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

คิดว่าหุ่นยนต์ควบคุมด้วยวิทยุในสนามการตรวจจับในกล่องปิดผนึกเป็นแบบจำลอง

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

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

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

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

ฉันตอบคำถามของคุณแล้วหรือยัง :-)

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

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

หากการตรวจสอบเสร็จสิ้นในมุมมองฉันจะใส่อะไรลงในคอนโทรลเลอร์

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

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

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

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


23

นี่คือบทความที่ดีเกี่ยวกับพื้นฐานของ MVC

มันระบุว่า ...

คอนโทรลเลอร์ - คอนโทรลเลอร์จะแปลการโต้ตอบกับมุมมองเป็นการกระทำที่จะดำเนินการโดยโมเดล

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

มีดีอีกอย่างก็คือบทความที่ฟาวเลอร์


MVP เป็นตัวเลือกอื่นที่กล่าวถึงในบทความที่คุณอ้างอิงดูmartinfowler.com/eaaDev/ModelViewPresenter.html
จอน

ขอบคุณสำหรับลิงค์พวกเขาทำให้อ่านน่าสนใจอย่างแน่นอน
Paul Walker

18

รูปแบบ MVC เพียงต้องการให้คุณแยกงานนำเสนอ (= มุมมอง) ออกจากตรรกะทางธุรกิจ (= แบบจำลอง) ส่วนควบคุมมีไว้เพื่อทำให้เกิดความสับสนเท่านั้น


1
สิ่งที่ฉันคิดเสมอมาจนถึงตอนนี้ แต่ไม่กล้าบอกใครเลย .... หรืออาจไม่สามารถพูดออกมาได้ด้วยคำพูดที่เหมาะสม
user1451111

1
Model-View-Confusion
ฝนตก

10

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

โดยส่วนตัวแล้ว MVC ที่ถูกเป่าเต็มดูเหมือนว่ารูปแบบการออกแบบจากโรงงานซึ่งนำไปสู่การออกแบบที่สับสนและซับซ้อนได้ง่าย อย่าเป็นนักบินอวกาศสถาปัตยกรรม


9

จากคำถามของคุณฉันได้รับความประทับใจว่าคุณมีหมอกในบทบาทของ Model โมเดลถูกแก้ไขบนข้อมูลที่เชื่อมโยงกับแอ็พพลิเคชัน หากแอพมีฐานข้อมูลงานของ Model จะคุยกับมัน นอกจากนี้ยังจะจัดการกับตรรกะง่ายๆที่เกี่ยวข้องกับข้อมูลนั้น หากคุณมีกฎที่บอกว่าสำหรับทุกกรณีที่ TABLE.foo == "ไชโย!" และ TABLE.bar == "Huzzah!" จากนั้นตั้งค่า TABLE.field = "W00t!" จากนั้นคุณต้องการให้ Model ดูแลมัน

คอนโทรลเลอร์เป็นสิ่งที่ควรจัดการกับพฤติกรรมของแอปพลิเคชั่นจำนวนมาก ดังนั้นเพื่อตอบคำถามของคุณ:

ฉันจะทำให้โมฆะสาธารณะ actionPerformed (ActionEvent e) ในมุมมองด้วยการเรียกวิธีการในคอนโทรลเลอร์หรือไม่?

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

ถ้าเป็นเช่นนั้นควรมีการตรวจสอบความถูกต้อง ฯลฯ ในคอนโทรลเลอร์หรือไม่?

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

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

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

จากประสบการณ์ของฉันการสื่อสารโดยตรงระหว่างตัวแบบและมุมมองควร จำกัด มากและมุมมองไม่ควรแก้ไขข้อมูลใด ๆ ของแบบจำลองโดยตรง นั่นควรจะเป็นงานของผู้ควบคุม

หากการตรวจสอบเสร็จสิ้นในมุมมองฉันจะใส่อะไรลงในคอนโทรลเลอร์

ดูด้านบน; การตรวจสอบที่แท้จริงควรอยู่ในตัวควบคุม และหวังว่าคุณจะมีความคิดเกี่ยวกับสิ่งที่ควรใส่ในตัวควบคุมโดยตอนนี้ :-)

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


7

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

ชั้นบริการเป็นสิ่งที่รู้กรณีการใช้งานของหน่วยงานและวัตถุรูปแบบ ตัวควบคุมจะแตกต่างกันสำหรับมุมมองแต่ละประเภท - คุณจะไม่มีตัวควบคุมเดียวกันสำหรับเดสก์ท็อปเบราว์เซอร์ที่ใช้ Flex หรือ UIs บนมือถือ ดังนั้นฉันจึงบอกว่ามันเป็นส่วนหนึ่งของ UI จริงๆ

บริการที่มุ่งเน้น: นั่นคือสิ่งที่งานจะทำ


3

คอนโทรลเลอร์ใช้สำหรับการประสานงานระหว่างมุมมองและโมเดลเป็นหลัก

โชคไม่ดีที่บางครั้งมันก็ปะปนกับมุมมอง - ในแอพขนาดเล็กแม้ว่ามันจะไม่เลวร้ายนัก

ฉันแนะนำให้คุณใส่:

public void actionPerformed(ActionEvent e)

ในตัวควบคุม จากนั้นผู้ฟังการกระทำของคุณในมุมมองของคุณควรมอบหมายให้ผู้ควบคุม

สำหรับส่วนการตรวจสอบคุณสามารถวางไว้ในมุมมองหรือตัวควบคุมฉันเองคิดว่ามันเป็นของตัวควบคุม

ฉันขอแนะนำให้ดูที่ Passive View และ Supervising Presenter (ซึ่งเป็นสิ่งสำคัญที่ Model View Presenter แบ่งออกเป็นอย่างน้อยโดย Fowler) ดู:

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html


3

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

ฉันได้รับสิ่งนี้หลังจากทำงานกับเว็บแอพขนาดใหญ่ที่เขียนโดยนักพัฒนาที่คิดว่าพวกเขาเข้าใจ MVC แต่ไม่จริง "ตัวควบคุม" ของพวกเขาลดลงเหลือแปดบรรทัดในการเรียกใช้เมธอดคลาสสแตติกที่เรียกว่าไม่มีที่อื่นเลย: - / ทำให้แบบจำลองของพวกเขาน้อยกว่าวิธีสร้างเนมสเปซ การปรับเปลี่ยนใหม่อย่างถูกต้องทำสามสิ่ง: เปลี่ยน SQL ทั้งหมดเป็น data access layer (aka model) ทำให้รหัสคอนโทรลเลอร์เป็น verbose มากขึ้นเล็กน้อย แต่เข้าใจได้ดีขึ้นมากและลดไฟล์ "model" เก่าไปเป็นอะไร :-)


1

นอกจากนี้โปรดทราบว่าวิดเจ็ต Swing แต่ละรายการสามารถพิจารณาว่ามีองค์ประกอบ MVC สามรายการ: แต่ละรายการมี Model (เช่น ButtonModel), View (BasicButtonUI) และ Control (JButton เอง)


1

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

อย่างไรก็ตามการใช้ MVC ที่เหมาะสมจะมีการโต้ตอบดังต่อไปนี้เท่านั้น: โมเดล -> มุมมองการดู -> คอนโทรลเลอร์คอนโทรลเลอร์ -> มุมมอง

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


0

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


0

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

(1) (การตอบสนองปฏิกิริยา - สิ่งที่ webapp "ทำ" เพื่อตอบสนองต่อผู้ใช้) Blog_Controller

-> () หลัก

-> handleSubmit_AddNewCustomer ()

-> verifyUser_HasProperAuth ()

(2) ตรรกะ ("ธุรกิจ" สิ่งที่และวิธีการที่ webapp "คิด") Blog_Logic

-> sanityCheck_AddNewCustomer ()

-> handleUsernameChange ()

-> sendEmail_NotifyRequestedUpdate ()

(3) (มุมมอง, พอร์ทัล, วิธีที่ webapp "ปรากฏ") Blog_View

-> genWelcome ()

-> genForm_AddNewBlogEntry ()

-> genPage_DataEntryForm ()

(4) (วัตถุข้อมูลเท่านั้นที่ได้มาใน _ construct () ของแต่ละบล็อก * แต่ละชั้นใช้เพื่อเก็บข้อมูล webapp / inmemory ทั้งหมดไว้ด้วยกันเป็นวัตถุเดียว) Blog_Meta

(5) (ชั้นข้อมูลพื้นฐานอ่าน / เขียนไปยัง DBs) Blog_Model

-> saveDataToMemcache ()

-> saveDataToMongo ()

-> saveDataToSql ()

-> LoadData ()

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

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