รู้เบื้องต้นเกี่ยวกับสถาปัตยกรรม MVC
สถาปัตยกรรมแอปพลิเคชันยอดนิยมที่โปรแกรมเมอร์ทุกคนรู้จักคือMVC MVC ย่อมาจากModel-View- Controller
นี่ไม่ใช่สถาปัตยกรรมของแอปพลิเคชันมากเท่าสถาปัตยกรรมของส่วนประกอบแอปพลิเคชัน แต่เราจะกลับไปที่ความแตกต่างเล็กน้อยนี้ในภายหลัง MVC คืออะไร?
MVC เป็นโครงร่างสำหรับการแยกข้อมูลแอปพลิเคชันและลอจิกการควบคุมออกเป็นสามส่วนประกอบแยกกัน ได้แก่รุ่น มุมมอง และตัวควบคุมเพื่อให้แต่ละส่วนประกอบสามารถแก้ไขได้อย่างอิสระ
- โมเดล (Model)ให้ข้อมูลและตอบสนองต่อคำสั่งคอนโทรลเลอร์โดยการเปลี่ยนสถานะ
- มุมมองมีหน้าที่รับผิดชอบในการแสดงข้อมูลแบบจำลองให้กับผู้ใช้เพื่อตอบสนองต่อการเปลี่ยนแปลงแบบจำลอง
- ตัวควบคุม (ตัวควบคุม)ตีความการกระทำของผู้ใช้โดยแจ้งรูปแบบถึงความจำเป็นในการเปลี่ยนแปลง
โมเดลนี้ถูกประดิษฐ์ขึ้นในปี 1978 (!) ปี ใช่ ปัญหาเกี่ยวกับสถาปัตยกรรมซอฟต์แวร์ที่เหมาะสมนั้นมีความเกี่ยวข้องเมื่อ 50 ปีที่แล้ว นี่คือวิธีที่โมเดลนี้อธิบายโดยไดอะแกรมในต้นฉบับ:
![รู้เบื้องต้นเกี่ยวกับสถาปัตยกรรม MVC](https://cdn.codegym.cc/images/article/f0c1243a-0dbc-445d-9cff-fe34276351af/original.jpeg)
แบบจำลองให้ข้อมูลและวิธีการทำงานกับพวกเขา: สืบค้นไปยังฐานข้อมูล, ตรวจสอบความถูกต้อง โมเดลเป็นอิสระจากมุมมอง (ไม่ทราบวิธีแสดงข้อมูล) และตัวควบคุม (ไม่มีจุดโต้ตอบของผู้ใช้) ซึ่งให้การเข้าถึงและการจัดการข้อมูล
แบบจำลองถูกสร้างขึ้นในลักษณะที่ตอบสนองต่อคำขอโดยการเปลี่ยนสถานะ และสามารถสร้างการแจ้งเตือนของ "ผู้สังเกตการณ์" ได้ แบบจำลอง เนื่องจากความเป็นอิสระจากการแสดงภาพ จึงสามารถมีการแสดงที่แตกต่างกันได้หลายแบบสำหรับ "แบบจำลอง" เดียว
มุมมองมีหน้าที่รับข้อมูลที่จำเป็นจากแบบจำลองและส่งไปยังผู้ใช้ มุมมองไม่ประมวลผลอินพุตของผู้ใช้
ตัวควบคุมจัดเตรียม "การสื่อสาร" ระหว่างผู้ใช้และระบบ ควบคุมและนำข้อมูลจากผู้ใช้ไปยังระบบและในทางกลับกัน ใช้แบบจำลองและมุมมองเพื่อดำเนินการตามที่ต้องการ
มีปัญหาบางประการเกี่ยวกับข้อเท็จจริงที่ว่าโมเดลนี้มีวิวัฒนาการเพียงเล็กน้อยในช่วงหลายทศวรรษที่ผ่านมา นั่นคือชื่อยังคงเหมือนเดิม แต่จุดประสงค์ของชิ้นส่วนเริ่มเปลี่ยนไป
สถาปัตยกรรม MVC บนเว็บ
แนวคิดเบื้องหลังรูปแบบการออกแบบ MVC นั้นง่ายมาก เราจำเป็นต้องแยกความรับผิดชอบสำหรับลักษณะการทำงานที่แตกต่างกันในแอปพลิเคชันของเราให้ชัดเจน:
แบบอย่าง— การประมวลผลข้อมูลและตรรกะของแอปพลิเคชัน
ดู— ให้ข้อมูลแก่ผู้ใช้ในรูปแบบที่รองรับ
ผู้ควบคุม- ประมวลผลคำขอของผู้ใช้และเรียกทรัพยากรที่เหมาะสม
แอปพลิเคชันแบ่งออกเป็นสามส่วนหลัก ซึ่งแต่ละส่วนจะรับผิดชอบงานที่แตกต่างกัน มาดูส่วนประกอบของแอปพลิเคชันไคลเอ็นต์เซิร์ฟเวอร์อย่างละเอียดยิ่งขึ้นโดยใช้ตัวอย่าง
ผู้ควบคุม
ผู้ใช้คลิกที่องค์ประกอบต่างๆ บนหน้าในเบราว์เซอร์ ซึ่งเป็นผลมาจากการที่เบราว์เซอร์ส่งคำขอ HTTP ต่างๆ: GET, POST หรืออื่นๆ ตัวควบคุมสามารถรวมเบราว์เซอร์และโค้ด JS ที่ทำงานภายในเพจได้
หน้าที่หลักของคอนโทรลเลอร์ในกรณีนี้คือการเรียกใช้เมธอดบนวัตถุที่จำเป็น จัดการการเข้าถึงทรัพยากรเพื่อดำเนินการตามที่ผู้ใช้ระบุ โดยทั่วไปแล้ว ตัวควบคุมจะเรียกโมเดลที่เหมาะสมสำหรับงานและเลือกมุมมองที่เหมาะสม
แบบอย่าง
แบบจำลองในแง่กว้างคือข้อมูลและกฎที่ใช้ในการทำงานกับข้อมูล - เมื่อรวมกันแล้วจะเป็นตรรกะทางธุรกิจของแอปพลิเคชัน การออกแบบแอปพลิเคชันเริ่มต้นด้วยการสร้างแบบจำลองของวัตถุที่ใช้งานอยู่เสมอ
สมมติว่าเรามีร้านค้าออนไลน์ที่ขายหนังสือ แล้วบุคคลนั้นเป็นเพียงผู้ใช้แอปพลิเคชันหรือเป็นผู้แต่งหนังสือด้วยหรือไม่ ต้องตอบคำถามสำคัญเหล่านี้ในระหว่างการออกแบบแบบจำลอง
นอกจากนี้ยังมีชุดของกฎ: อะไรทำได้ อะไรทำไม่ได้ ชุดข้อมูลใดยอมรับได้และไม่ยอมรับ หนังสือสามารถอยู่ได้โดยไม่มีผู้แต่ง? และผู้แต่งที่ไม่มีหนังสือ? วันเกิดของผู้ใช้สามารถเป็นปี 300 เป็นต้นไปได้หรือไม่
แบบจำลองทำให้คอนโทรลเลอร์มองเห็นข้อมูลที่ผู้ใช้ร้องขอ (ข้อความ หน้าหนังสือ รูปภาพ ฯลฯ) โมเดลข้อมูลจะเหมือนกันไม่ว่าเราจะต้องการนำเสนอแก่ผู้ใช้อย่างไร ดังนั้นเราจึงเลือกมุมมองที่มีอยู่เพื่อแสดงข้อมูล
โมเดลประกอบด้วยส่วนที่สำคัญที่สุดของตรรกะแอปพลิเคชันของเราตรรกะที่แก้ปัญหาที่เรากำลังเผชิญอยู่ (ฟอรัม ร้านค้า ธนาคาร ฯลฯ) ตัวควบคุมมีตรรกะขององค์กรเป็นส่วนใหญ่สำหรับแอปพลิเคชันเอง (เช่นเดียวกับผู้จัดการโครงการของคุณ)
ดู
มุมมองมีวิธีต่างๆ ในการแสดงข้อมูลที่ได้รับจากแบบจำลอง อาจเป็นเทมเพลตที่เต็มไปด้วยข้อมูล อาจมีมุมมองที่แตกต่างกันหลายมุมมองและผู้ควบคุมจะเลือกมุมมองที่ดีที่สุดสำหรับสถานการณ์ปัจจุบัน
เว็บแอปพลิเคชันมักจะประกอบด้วยชุดตัวควบคุม แบบจำลอง และมุมมอง คอนโทรลเลอร์สามารถอยู่ในแบ็กเอนด์เท่านั้น แต่ยังสามารถมีคอนโทรลเลอร์หลายตัวที่แตกต่างกันได้ เมื่อลอจิกของมันกระจายไปทั่วส่วนหน้าด้วย ตัวอย่างที่ดีของแนวทางนี้คือแอปพลิเคชันมือถือใดๆ
ตัวอย่าง MVC บนเว็บ
สมมติว่าคุณต้องพัฒนาร้านค้าออนไลน์ที่จะขายหนังสือ ผู้ใช้สามารถดำเนินการดังต่อไปนี้: ดูหนังสือ ลงทะเบียน ซื้อ เพิ่มรายการในคำสั่งซื้อปัจจุบัน ทำเครื่องหมายหนังสือที่เขาชอบและซื้อ
แอปพลิเคชันของคุณควรมีโมเดลที่รับผิดชอบตรรกะทางธุรกิจทั้งหมด คุณต้องมีตัวควบคุมที่จะประมวลผลการกระทำของผู้ใช้ทั้งหมดและเปลี่ยนให้เป็นวิธีการเรียกจากตรรกะทางธุรกิจ อย่างไรก็ตาม เมธอดคอนโทรลเลอร์หนึ่งเมธอดสามารถเรียกเมธอดโมเดลต่างๆ ได้มากมาย
คุณต้องมีชุดมุมมอง: รายการหนังสือ ข้อมูลเกี่ยวกับหนังสือเล่มหนึ่ง ตะกร้าสินค้า รายการคำสั่งซื้อ แต่ละหน้าของเว็บแอ็พพลิเคชันเป็นมุมมองแยกต่างหากที่แสดงลักษณะเฉพาะของโมเดลให้ผู้ใช้เห็น
มาดูกันว่าจะเกิดอะไรขึ้นหากผู้ใช้เปิดรายการหนังสือแนะนำของร้านหนังสือเพื่อดูชื่อเรื่อง ลำดับของการกระทำทั้งหมดสามารถอธิบายได้ในรูปแบบของ 6 ขั้นตอน:
![ตัวอย่าง MVC บนเว็บ](https://cdn.codegym.cc/images/article/a7f52906-62ff-44d9-8cb4-3357b5b9fe63/800.jpeg)
ขั้นตอน:
- ผู้ใช้คลิกลิงก์ "แนะนำ" และเบราว์เซอร์ส่งคำขอไปที่ /books/recommendations
- ตัวควบคุมตรวจสอบคำขอ : ผู้ใช้ต้องเข้าสู่ระบบ หรือเราควรจะรวบรวมหนังสือสำหรับผู้ใช้ที่ไม่ได้เข้าสู่ระบบ จากนั้นคอนโทรลเลอร์จะเรียกโมเดลและขอให้ส่งคืนรายการหนังสือที่แนะนำให้กับผู้ใช้ N
- โมเดลเข้าถึงฐานข้อมูล ดึงข้อมูลเกี่ยวกับหนังสือจากที่นั่น: หนังสือที่กำลังเป็นที่นิยม หนังสือที่ผู้ใช้ซื้อ หนังสือที่เพื่อนซื้อ หนังสือจากรายการที่เขาต้องการ จากข้อมูลนี้ โมเดลจะสร้างรายการหนังสือที่แนะนำ 10 เล่มและส่งคืนไปยังตัวควบคุม
- ผู้ควบคุมได้รับรายชื่อหนังสือที่แนะนำและดู ในขั้นตอนนี้ ผู้ควบคุมเป็นผู้ตัดสินใจ! หากมีหนังสือน้อยหรือรายการว่างเปล่า ระบบจะขอรายการหนังสือสำหรับผู้ใช้ที่ไม่ได้เข้าสู่ระบบ หากมีโปรโมชันอยู่ในตอนนี้ ผู้ควบคุมสามารถเพิ่มหนังสือโปรโมชันลงในรายการได้
- ตัวควบคุมกำหนดหน้าที่จะแสดงต่อผู้ใช้ อาจเป็นหน้าแสดงข้อผิดพลาด หน้าที่มีรายชื่อหนังสือ หน้าแสดงความยินดีที่ผู้ใช้กลายเป็นผู้เยี่ยมชมคนที่ล้าน
- เซิร์ฟเวอร์ให้ไคลเอนต์เพจ ( ดู ) ที่ผู้ควบคุมเลือก กรอกข้อมูลที่จำเป็น (ชื่อผู้ใช้ รายชื่อหนังสือ) และไปที่ลูกค้า
- ลูกค้าได้รับเพจและแสดงให้ผู้ใช้เห็น
ประโยชน์ของแนวทางนี้คืออะไร?
ข้อได้เปรียบที่ชัดเจนที่สุดที่เราได้รับจากการใช้แนวคิด MVC คือการแยกตรรกะของการนำเสนอ (ส่วนติดต่อผู้ใช้) และตรรกะของแอปพลิเคชัน (แบ็กเอนด์) ออกจากกันอย่างชัดเจน
ข้อได้เปรียบประการที่สองคือการแบ่งส่วนเซิร์ฟเวอร์ออกเป็นสองส่วน: โมเดลอัจฉริยะ ( ตัวดำเนินการ ) และตัวควบคุม ( ศูนย์การตัดสินใจ )
ในตัวอย่างก่อนหน้านี้ มีช่วงหนึ่งที่คอนโทรลเลอร์สามารถรับรายการหนังสือแนะนำที่ว่างเปล่าจากโมเดลและตัดสินใจว่าจะทำอย่างไรกับมัน ในทางทฤษฎี ตรรกะนี้สามารถใส่ลงในแบบจำลองได้โดยตรง
อันดับแรก เมื่อขอหนังสือแนะนำ นางแบบจะตัดสินใจว่าจะทำอย่างไรหากรายการนั้นว่างเปล่า แล้วผมจะต้องใส่โค้ดที่เดิม ทำไงดี ถ้าตอนนี้มีโปรอยู่ แล้วมี option ต่างๆ เพิ่มขึ้น
จากนั้นปรากฎว่าผู้ดูแลร้านค้าต้องการดูว่าหน้าของผู้ใช้จะดูเป็นอย่างไรหากไม่มีการโปรโมต หรือในทางกลับกัน ตอนนี้ไม่มีการโปรโมต แต่เขาต้องการดูว่าการโปรโมตในอนาคตจะแสดงอย่างไร และไม่มีวิธีการนี้ ดังนั้นจึงมีการตัดสินใจแยกศูนย์การตัดสินใจ (ตัวควบคุม) ออกจากตรรกะทางธุรกิจ (แบบจำลอง)
นอกจากการแยกมุมมองออกจากตรรกะของแอปพลิเคชันแล้ว แนวคิด MVC ยังช่วยลดความซับซ้อนของแอปพลิเคชันขนาดใหญ่ได้อย่างมาก โค้ดมีโครงสร้างมากขึ้น ทำให้ง่ายต่อการบำรุงรักษา ทดสอบ และนำโซลูชันกลับมาใช้ใหม่
เมื่อเข้าใจแนวคิดของ MVC ในฐานะนักพัฒนา คุณจะรู้ว่าต้องเพิ่มการเรียงลำดับรายการหนังสือในจุดใด:
- ที่ระดับแบบสอบถามฐานข้อมูล
- ในระดับตรรกะทางธุรกิจ (แบบจำลอง)
- ที่ระดับตรรกะทางธุรกิจ (ตัวควบคุม)
- ในมุมมอง - ในฝั่งไคลเอนต์
และนี่ไม่ใช่คำถามเชิงโวหาร ตอนนี้ ลองนึกถึงตำแหน่งและเหตุผลที่คุณต้องเพิ่มรหัสสำหรับการจัดเรียงรายการหนังสือ
โมเดล MVC คลาสสิค
การโต้ตอบระหว่างส่วนประกอบ MVC ถูกนำมาใช้แตกต่างกันในเว็บแอปพลิเคชันและแอปพลิเคชันมือถือ นี่เป็นเพราะเว็บแอปมีอายุสั้น ประมวลผลคำขอของผู้ใช้หนึ่งรายการแล้วออก ในขณะที่แอปมือถือประมวลผลคำขอจำนวนมากโดยไม่ต้องรีสตาร์ท
โดยทั่วไปเว็บแอปพลิเคชันจะใช้โมเดล "แบบพาสซีฟ" ในขณะที่แอปพลิเคชันมือถือจะใช้โมเดล "แอคทีฟ" โมเดลที่ใช้งานซึ่งแตกต่างจากโมเดลแบบพาสซีฟช่วยให้คุณสามารถสมัครรับข้อมูลและรับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงได้ สิ่งนี้ไม่จำเป็นสำหรับเว็บแอปพลิเคชัน
นี่คือลักษณะของการทำงานร่วมกันของส่วนประกอบในรุ่นต่างๆ:
![โมเดล MVC คลาสสิค](https://cdn.codegym.cc/images/article/08f6a9ed-262d-4930-ac41-b9d8fe23027f/1024.jpeg)
แอปพลิเคชันมือถือ (รุ่นที่ใช้งานอยู่) ใช้เหตุการณ์และกลไกการสมัครสมาชิกเหตุการณ์ ด้วยวิธีการนี้ มุมมอง ( view ) สมัครรับการเปลี่ยนแปลงโมเดล จากนั้น เมื่อเหตุการณ์ บางอย่างเกิดขึ้น (เช่น ผู้ใช้คลิกปุ่ม) จะเรียก ตัวควบคุม นอกจากนี้ยังให้ คำสั่ง แก่โมเดลเพื่อเปลี่ยนข้อมูล
หากข้อมูลบางส่วนมีการเปลี่ยนแปลง โมเดลจะสร้างเหตุการณ์เกี่ยวกับการเปลี่ยนแปลงข้อมูลนี้ มุมมองทั้งหมดที่สมัครรับข้อมูลเหตุการณ์นี้ (ซึ่งเป็นสิ่งสำคัญที่จะต้องเปลี่ยนข้อมูลเฉพาะนี้) จะได้รับเหตุการณ์นี้และอัปเดตข้อมูลในอินเทอร์เฟซ
ในเว็บแอปพลิเคชัน สิ่งต่างๆ จะถูกจัดระเบียบแตกต่างกันเล็กน้อย ข้อแตกต่างหลักทางเทคนิคคือ ไคลเอน ต์ไม่สามารถรับข้อความฝั่งเซิร์ฟเวอร์จากการเริ่มต้นของเซิร์ฟเวอร์
ดังนั้นตัวควบคุมในเว็บแอปพลิเคชันมักจะไม่ส่งข้อความใด ๆ ไปที่มุมมอง แต่ให้หน้าใหม่แก่ลูกค้า ซึ่งในทางเทคนิคแล้วเป็นมุมมองใหม่หรือแม้แต่แอปพลิเคชันไคลเอนต์ใหม่ (หากหน้าหนึ่งไม่รู้อะไรเกี่ยวกับอีกหน้าหนึ่ง) .
ในปัจจุบัน ปัญหานี้ได้รับการแก้ไขบางส่วนโดยใช้แนวทางต่อไปนี้:
- การสำรวจเซิร์ฟเวอร์เป็นประจำสำหรับการเปลี่ยนแปลงข้อมูลสำคัญ (นาทีละครั้งหรือมากกว่า)
- WebSockets อนุญาตให้ไคลเอนต์สมัครรับข้อความเซิร์ฟเวอร์
- การแจ้งเตือนแบบพุชของเว็บจากฝั่งเซิร์ฟเวอร์
- โปรโตคอล HTTP/2 อนุญาตให้เซิร์ฟเวอร์เริ่มต้นการส่งข้อความไปยังไคลเอ็นต์