MVC (Model, View, Controller) เป็นรูปแบบสำหรับการจัดระเบียบโค้ดในแอปพลิเคชันเพื่อปรับปรุงการบำรุงรักษา
สถาปัตยกรรมที่ไม่ใช่ MVC มีแนวโน้มที่จะรวมเข้าด้วยกันอย่างแน่นหนา ถ้ากล่องตัวควบคุมและกล้องเป็นวัตถุเดียวแล้วเราจะต้องแยกออกจากกันแล้วสร้างทั้งกล่องและกล้องใหม่ทุกครั้งที่เราต้องการได้มุมมองใหม่ นอกจากนี้การถ่ายรูปก็เหมือนพยายามถ่ายรูปเซลฟี่ - และนั่นก็ไม่ใช่เรื่องง่ายเสมอไป
bwaha wrote:
ผู้เขียนอ้างถึง mvctree.py ใน wxPython เป็นตัวอย่างของการออกแบบ MVC อย่างไรก็ตามฉันยังเป็นสีเขียวเกินไปดังนั้นฉันจึงพบว่าตัวอย่างที่ซับซ้อนเกินไปและฉันไม่เข้าใจถึงการแยกที่ผู้เขียนแนะนำ
MVC คือทั้งหมดที่เกี่ยวกับการแยกความกังวล
ตัวแบบมีหน้าที่ในการจัดการข้อมูลของโปรแกรม (ทั้งข้อมูลส่วนตัวและข้อมูลลูกค้า) View / Controller รับผิดชอบในการจัดหาโลกภายนอกด้วยวิธีการโต้ตอบกับข้อมูลลูกค้าของโปรแกรม
รุ่นนี้มีอินเทอร์เฟซภายใน (API) เพื่อให้ส่วนอื่น ๆ ของโปรแกรมโต้ตอบกับมัน View / Controller จัดเตรียมอินเทอร์เฟซภายนอก (GUI / CLI / เว็บฟอร์ม / IPC ระดับสูง / ฯลฯ ) เพื่อเปิดใช้งานทุกอย่างที่อยู่นอกโปรแกรมเพื่อสื่อสารกับมัน
ตัวแบบมีหน้าที่ในการรักษาความถูกต้องของข้อมูลของโปรแกรมเพราะถ้ามันได้รับความเสียหายมันจะจบลงสำหรับทุกคน มุมมอง / คอนโทรลเลอร์มีหน้าที่รับผิดชอบในการรักษาความสมบูรณ์ของ UI ตรวจสอบให้แน่ใจว่ามุมมองข้อความทั้งหมดแสดงค่าที่ทันสมัยปิดใช้งานรายการเมนูที่ไม่ได้ใช้กับโฟกัสปัจจุบัน ฯลฯ
โมเดลไม่มีโค้ดมุมมอง / คอนโทรลเลอร์ ไม่มีคลาสวิดเจ็ต GUI ไม่มีรหัสสำหรับการจัดวางกล่องโต้ตอบหรือรับอินพุตของผู้ใช้ View / Controller ไม่มีรหัสรุ่น ไม่มีรหัสสำหรับการตรวจสอบความถูกต้องของ URL หรือดำเนินการค้นหา SQL และไม่มีสถานะดั้งเดิมใด ๆ : ข้อมูลใด ๆ ที่จัดเก็บโดยวิดเจ็ตนั้นใช้สำหรับการแสดงผลเท่านั้นและเป็นเพียงภาพสะท้อนของข้อมูลจริงที่เก็บไว้ในแบบจำลอง
ตอนนี้นี่คือการทดสอบการออกแบบ MVC ที่แท้จริง: โปรแกรมควรจะทำงานได้อย่างสมบูรณ์แม้ว่าจะไม่มี View / Controller ติดอยู่ก็ตาม ตกลงโลกภายนอกจะมีปัญหาในการโต้ตอบกับมันในรูปแบบนั้น แต่ตราบใดที่ใคร ๆ รู้ถึงคาถา API แบบเหมาะสมโปรแกรมจะเก็บและจัดการข้อมูลตามปกติ
ทำไมเป็นไปได้ คำตอบง่ายๆคือทุกอย่างต้องขอบคุณการมีเพศสัมพันธ์ต่ำระหว่างเลเยอร์ Model และ View / Controller อย่างไรก็ตามนี่ไม่ใช่เรื่องเต็ม สิ่งสำคัญสำหรับรูปแบบ MVC ทั้งหมดคือทิศทางการเชื่อมต่อที่เกิดขึ้น: คำแนะนำทั้งหมดไหลจากมุมมอง / ตัวควบคุมไปยังแบบจำลอง รุ่นไม่เคยบอกมุมมอง / ตัวควบคุมว่าจะทำอย่างไร
ทำไม? เพราะใน MVC ในขณะที่มุมมอง / คอนโทรลเลอร์ได้รับอนุญาตให้รู้เล็กน้อยเกี่ยวกับ Model (โดยเฉพาะ API ของ Model) แต่ Model นั้นไม่ได้รับอนุญาตให้รู้อะไรเกี่ยวกับ View / Controller
ทำไม? เนื่องจาก MVC เป็นเรื่องเกี่ยวกับการสร้างการแยกข้อกังวลอย่างชัดเจน
ทำไม? เพื่อช่วยป้องกันความซับซ้อนของโปรแกรมที่เกิดจากการควบคุมและฝังคุณนักพัฒนาภายใต้ ยิ่งโปรแกรมใหญ่มากขึ้นเท่าไหร่จำนวนองค์ประกอบในโปรแกรมนั้นก็จะยิ่งมากขึ้นเท่านั้น และยิ่งมีการเชื่อมต่อระหว่างส่วนประกอบเหล่านั้นมากเท่าไรก็ยิ่งยากขึ้นสำหรับนักพัฒนาในการดูแลรักษา / ขยาย / แทนที่ส่วนประกอบแต่ละตัวหรือแม้เพียงแค่ติดตามการทำงานของระบบทั้งหมด ถามตัวเองว่า: เมื่อดูแผนภาพของโครงสร้างของโปรแกรมคุณจะเห็นต้นไม้หรือเปลแมวหรือไม่ รูปแบบ MVC หลีกเลี่ยงหลังโดยไม่อนุญาตการเชื่อมต่อแบบวงกลม: B สามารถเชื่อมต่อกับ A ได้ แต่ A ไม่สามารถเชื่อมต่อกับ B ในกรณีนี้ A คือรุ่นและ B เป็นมุมมอง / คอนโทรลเลอร์
BTW ถ้าคุณเฉียบแหลมคุณจะสังเกตเห็นปัญหาเกี่ยวกับข้อ จำกัด 'ทางเดียว' ที่อธิบายไว้: โมเดลจะแจ้งมุมมอง / คอนโทรลเลอร์ของการเปลี่ยนแปลงในข้อมูลผู้ใช้ของโมเดลได้อย่างไรเมื่อโมเดลไม่ได้รับอนุญาต รู้หรือไม่ว่า View / Controller ไม่สนใจที่จะส่งข้อความถึงมัน แต่ไม่ต้องกังวล: มีวิธีแก้ปัญหานี้และมันค่อนข้างเรียบร้อยแม้ว่ามันจะดูเป็นวงเวียนเล็กน้อยในตอนแรก เราจะกลับไปที่อีกสักครู่
ในทางปฏิบัติแล้ววัตถุ View / Controller อาจผ่าน API ของ Model 1 บอกให้ Model ทำสิ่งต่าง ๆ (รันคำสั่ง) และ 2 บอก Model ให้สิ่งต่าง ๆ (ส่งคืนข้อมูล) ชั้น View / Controller ส่ง
คำแนะนำไปยังเลเยอร์ Model และดึงข้อมูลจากเลเยอร์ Model
และนั่นคือสิ่งที่ตัวอย่าง MyCoolListControl แรกของคุณผิดพลาดเนื่องจาก API สำหรับคลาสนั้นต้องการข้อมูลที่จะถูกส่ง
เข้าไปดังนั้นคุณจะกลับมามีการเชื่อมต่อสองทางระหว่างเลเยอร์ละเมิดกฎ MVC และทิ้งคุณกลับเข้าไปใน สถาปัตยกรรมแท่นวางของแมวที่คุณเคยพยายามหลีกเลี่ยงตั้งแต่แรก
แต่คลาส MyCoolListControl ควรไปกับโฟลว์โดยดึงข้อมูลที่ต้องการจากเลเยอร์ด้านล่างเมื่อต้องการ ในกรณีของวิดเจ็ตรายการซึ่งโดยทั่วไปหมายถึงการถามว่ามีค่าจำนวนเท่าใดแล้วจึงขอให้แต่ละรายการเหล่านั้นหันมาเพราะนั่นเป็นวิธีที่ง่ายที่สุดและหลวมที่สุดในการทำเช่นนั้น และถ้าวิดเจ็ตต้องการบอกว่าจะนำเสนอค่าเหล่านั้นให้กับผู้ใช้ตามลำดับตัวอักษรที่ดีแล้วนั่นคือมัน perogative; และความรับผิดชอบของมันแน่นอน
ตอนนี้ปริศนาสุดท้ายที่ผ่านมาอย่างที่ฉันบอกไว้ก่อนหน้านี้: คุณจะทำให้จอแสดงผลของ UI ตรงกับสถานะของรุ่นในระบบที่ใช้ MVC ได้อย่างไร
นี่คือปัญหา: วัตถุ View หลายรายการมีสถานะเป็นมลรัฐเช่นช่องทำเครื่องหมายอาจถูกเลือกหรือไม่ถูกต้องฟิลด์ข้อความอาจมีข้อความที่แก้ไขได้ อย่างไรก็ตาม MVC กำหนดว่าข้อมูลผู้ใช้ทั้งหมดจะถูกเก็บไว้ในเลเยอร์โมเดลดังนั้นข้อมูลใด ๆ ที่จัดเก็บโดยเลเยอร์อื่นเพื่อวัตถุประสงค์ในการแสดงผล (สถานะของช่องทำเครื่องหมายข้อความปัจจุบันของฟิลด์ข้อความ) จึงต้องเป็นสำเนาย่อยของข้อมูลโมเดลหลักนั้น แต่หากสถานะของโมเดลเปลี่ยนแปลงไปสำเนาของมุมมองของรัฐนั้นจะไม่ถูกต้องอีกต่อไปและจำเป็นต้องรีเฟรช
แต่อย่างไร รูปแบบ MVC ป้องกันไม่ให้ Model ส่งสำเนาของข้อมูลนั้นไปยังเลเยอร์ View Heck ไม่อนุญาตให้ตัวแบบส่งข้อความดูว่าสถานะมีการเปลี่ยนแปลง
เกือบแล้ว ตกลงเลเยอร์โมเดลไม่ได้รับอนุญาตให้พูดคุยโดยตรงกับเลเยอร์อื่นเนื่องจากจะต้องมีความรู้เกี่ยวกับเลเยอร์เหล่านั้นและกฎ MVC จะป้องกันไม่ให้ อย่างไรก็ตามหากต้นไม้ล้มลงในป่าและไม่มีใครได้ยินเสียงมันจะส่งเสียงหรือไม่?
คำตอบที่คุณเห็นคือการตั้งค่าระบบการแจ้งเตือนโดยจัดเตรียมเลเยอร์โมเดลด้วยสถานที่ที่สามารถประกาศให้กับใครโดยเฉพาะว่ามันเพิ่งทำสิ่งที่น่าสนใจ เลเยอร์อื่น ๆ สามารถโพสต์ผู้ฟังด้วยระบบการแจ้งเตือนนั้นเพื่อฟังประกาศที่พวกเขาสนใจจริง ๆ เลเยอร์โมเดลไม่จำเป็นต้องรู้อะไรเกี่ยวกับว่าใครกำลังฟังอยู่ มันแค่โพสต์ประกาศแล้วก็ลืมไปเลย และถ้าใครได้ยินการประกาศนั้นและรู้สึกอยากทำอะไรบางอย่างในภายหลัง - เช่นขอให้ Model สำหรับข้อมูลใหม่บางอย่างเพื่อให้สามารถอัปเดตการแสดงผลบนหน้าจอได้ - ยอดเยี่ยมมาก ตัวแบบแสดงรายการที่การแจ้งเตือนที่ส่งเป็นส่วนหนึ่งของคำจำกัดความของ API และสิ่งที่คนอื่นทำกับความรู้นั้นขึ้นอยู่กับพวกเขา
MVC ถูกเก็บรักษาไว้และทุกคนมีความสุข เฟรมเวิร์กแอปพลิเคชันของคุณอาจมีระบบการแจ้งเตือนในตัวหรือคุณสามารถเขียนของคุณเองได้หากไม่ใช่ (ดูที่ 'รูปแบบผู้สังเกตการณ์')
...
อย่างไรก็ตามหวังว่าจะช่วยได้ เมื่อคุณเข้าใจแรงจูงใจที่อยู่เบื้องหลัง MVC สาเหตุที่ทำให้สิ่งต่าง ๆ เป็นไปตามที่พวกเขาเริ่มมีเหตุผลแม้เมื่อ - แวบแรกพวกเขาดูซับซ้อนกว่าที่จำเป็น
ไชโย
มี