ตัวแบบ–มุมมอง–ตัวควบคุม

right|thumb|220x220px| แผนภาพของการโต้ตอบภายในรูปแบบ MVC
**ตัวแบบ–มุมมอง–ตัวควบคุม** () หรือเรียกย่อว่า **MVC** เป็นแบบแผนการออกแบบซอฟต์แวร์ ที่ใช้กันทั่วไปสำหรับการพัฒนาส่วนต่อประสานกับผู้ใช้ที่แบ่งตรรกะของโปรแกรมที่เกี่ยวข้องออกเป็นสามองค์ประกอบที่เชื่อมต่อถึงกัน องค์ประกอบเหล่านี้คือการแสดงข้อมูลภายใน (**ตัวแบบ**) อินเทอร์เฟซ (**มุมมอง**) ที่นำเสนอข้อมูลและรับข้อมูลจากผู้ใช้ และซอฟต์แวร์**ตัวควบคุม** ที่เชื่อมโยงทั้งสอง

เดิมใช้สำหรับส่วนติดต่อผู้ใช้แบบกราฟิกบนเดสก์ท็อป (GUI) แต่ต่อมารูปแบบนี้ก็ได้รับความนิยมในการออกแบบโปรแกรมประยุกต์บนเว็บด้วย ภาษาโปรแกรมยอดนิยมมีเฟรมเวิร์ก MVC ที่อำนวยความสะดวกในการใช้งานรูปแบบนี้

## ความเป็นมา
หนึ่งในข้อมูลเชิงลึกที่สำคัญในการพัฒนาส่วนต่อประสานผู้ใช้แบบกราฟิกในช่วงแรก MVC กลายเป็นหนึ่งในแนวทางแรก ๆ ในการอธิบายและใช้งานโครงสร้างซอฟต์แวร์ในแง่ของความรับผิดชอบ

Trygve Reenskaug สร้าง MVC ในขณะที่ทำงานกับ Smalltalk -79 ในฐานะนักวิทยาศาสตร์รับเชิญที่ Xerox Palo Alto Research Center (PARC) ในช่วงปลายทศวรรษ 1970 เขาต้องการรูปแบบที่สามารถใช้เพื่อจัดโครงสร้างโปรแกรมใด ๆ ที่ผู้ใช้โต้ตอบกับชุดข้อมูลขนาดใหญ่และซับซ้อน การออกแบบของเขาในตอนแรกมีสี่ส่วน: ตัวแบบ มุมมอง สิ่งของ และบรรณาธิการ หลังจากหารือกับนักพัฒนา Smalltalk คนอื่น ๆ แล้ว เขาและคนอื่น ๆ ในกลุ่มก็ตกลงเปลี่ยนเป็นตัวแบบ มุมมอง และตัวควบคุมแทน

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

Smalltalk-80 รองรับเวอร์ชันของ MVC ที่พัฒนามาจากเวอร์ชันนี้ โดยจัดให้มีคลาสนามธรรมคือ `view` และ `controller` รวมถึงคลาสย่อยที่เป็นรูปธรรมต่าง ๆ ของแต่ละคลาสที่แสดงถึงวิดเจ็ตทั่วไปที่แตกต่างกัน ในรูปแบบนี้ `View` แสดงถึงวิธีการแสดงข้อมูลแก่ผู้ใช้ และ `controller` แสดงถึงวิธีการบางอย่างที่ผู้ใช้โต้ตอบกับมุม `view` `นอกจากนี้ view` ยังเชื่อมโยงกับตัวแบบวัตถุด้วย แต่โครงสร้างของวัตถุนั้นขึ้นอยู่กับโปรแกรมเมอร์โปรแกรมประยุกต์ สภาพแวดล้อม Smalltalk-80 ยังมี "MVC Inspector" ซึ่งเป็นเครื่องมือพัฒนาสำหรับการดูโครงสร้างของตัวแบบ มุมมอง และตัวควบคุมที่กำหนดเคียงข้างกัน

ในปี 1988 บทความใน *[[วารสารเทคโนโลยีออบเจ็กต์|The Journal of Object Technology]]* (JOT) โดยอดีตพนักงาน PARC สองคน นำเสนอ MVC ว่าเป็น "กระบวนทัศน์และวิธีการเขียนโปรแกรม" ทั่วไปสำหรับนักพัฒนา Smalltalk-80 อย่างไรก็ตาม ผังของพวกเขาแตกต่างไปจากผังของ Reenskaug และคณะ และผังของหนังสืออ้างอิง Smalltalk-80 พวกเขากำหนดมุมมองว่าครอบคลุมความต้องการด้านกราฟิก โดยตัวควบคุมจะเป็นวัตถุที่เป็นนามธรรมและมองไม่เห็นโดยทั่วไป ซึ่งรับอินพุตจากผู้ใช้และโต้ตอบกับหนึ่งหรือหลายมุมมองและมีเพียงตัวแบบเดียวเท่านั้น

รูปแบบ MVC ได้รับการพัฒนาในเวลาต่อมา ก่อให้เกิดสำเนียงต่าง ๆ เช่น hierarchical model–view–controller (HMVC), model–view–adapter (MVA), model–view–presenter (MVP), model–view–viewmodel (MVVM) และอื่น ๆ ที่ปรับ MVC ให้เข้ากับบริบทที่แตกต่างกัน

การใช้รูปแบบ MVC ในโปรแกรมประยุกต์บนเว็บเพิ่มขึ้นหลังจากการเปิดตัวWebObjects ของ NeXT ในปี 1996 ซึ่งเดิมเขียนด้วย Objective-C (ซึ่งยืมมาจาก Smalltalk เป็นจำนวนมาก) และช่วยบังคับใช้หลักการ MVC ต่อมา รูปแบบ MVC ได้รับความนิยมจากนักพัฒนา Java เมื่อ WebObjects ถูกย้ายไปยัง Java เฟรมเวิร์กรุ่นต่อมาสำหรับ Java เช่น Spring (เปิดตัวในเดือนตุลาคม 2002) ยังคงสานต่อความสัมพันธ์อันแน่นแฟ้นระหว่าง Java และ MVC

ในปี 2003 Martin Fowler ได้ตีพิมพ์ *Patterns of Enterprise Application Architecture* ซึ่งนำเสนอ MVC เป็นรูปแบบที่ "input controller" ได้รับการร้องขอ ส่งข้อความที่เหมาะสมไปยังวัตถุตัวแบบรับการตอบสนองจากวัตถุตัวแบบ และส่งการตอบสนองไปยัง มุมมองที่เหมาะสมสำหรับการแสดงผล > ซึ่งใกล้เคียงกับแนวทางที่ดำเนินการโดยเฟรมเวิร์กแอปพลิเคชันเว็บ Ruby on Rails (สิงหาคม 2004) ซึ่งมีไคลเอ็นต์ส่งคำขอไปยังเซิร์ฟเวอร์ผ่านมุมมองในเบราว์เซอร์ คำขอเหล่านี้ได้รับการจัดการโดยตัวควบคุมบนเซิร์ฟเวอร์ และตัวควบคุม สื่อสารกับวัตถุโมเดลที่เหมาะสม เฟรมเวิร์ก Django (กรกฎาคม 2005 สำหรับ Python ) หยิบยก "มุมมองแม่แบบตัวแบบ" (model template view หรือ MTV) ที่คล้ายกันมาใช้ ซึ่งมุมมองจะดึงข้อมูลจากตัวแบบและส่งผ่านไปยังแม่แบบเพื่อแสดงผล ทั้ง Rails และ Django เปิดตัวโดยเน้นไปที่การ deploy ได้รวดเร็ว ซึ่งเพิ่มความนิยมของ MVC นอกเหนือไปจากสภาพแวดล้อมองค์กรแบบเดิม (ซึ่งได้รับความนิยมมายาวนาน)

## องค์ประกอบ

### ตัวแบบ
องค์ประกอบตรงกลางของรูปแบบ เป็นโครงสร้างข้อมูลแบบพลวัตของโปรแกรมประยุกต์ โดยไม่ขึ้นอยู่กับอินเทอร์เฟซผู้ใช้ โดยจะจัดการข้อมูล ตรรกะ และกฎของแอปพลิเคชันโดยตรง ใน Smalltalk-80 การออกแบบประเภทตัวแบบนั้นขึ้นอยู่กับโปรแกรมเมอร์ทั้งหมด ด้วย WebObjects, Rails และ Django โดยทั่วไปประเภทตัวแบบจะแสดงถึงตารางในฐานข้อมูลของโปรแกรมประยุกต์

### มุมมอง
การแสดงข้อมูลใดๆ เช่น แผนภูมิ แผนภาพ หรือตาราง สามารถดูข้อมูลเดียวกันได้หลายมุมมอง เช่น แผนภูมิแท่งสำหรับการจัดการและมุมมองแบบตารางสำหรับนักบัญชี

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

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

มุมมองใน Smalltalk-80 สื่อสารกับทั้งตัวแบบและตัวควบคุม ในขณะที่ WebObjects มุมมองจะพูดคุยกับตัวควบคุมเท่านั้น จากนั้นจะพูดคุยกับโมเดล ด้วย Rails และ Django ตัวควบคุม/มุมมองจะใช้มุมมอง/เทมเพลตเมื่อเตรียมการตอบสนองต่อไคลเอนต์ 

### ตัวควบคุม
ตัวควบคุมรับอินพุตและแปลงเป็นคำสั่งสำหรับตัวแบบหรือมุมมอง

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

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

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

Django เรียกวัตถุที่มีบทบาทนี้ว่า "มุมมอง" แทนที่จะเป็นตัวควบคุม มุมมอง Django เป็นฟังก์ชันที่รับคำขอทางเว็บและส่งคืนการตอบกลับทางเว็บ อาจใช้เทมเพลตเพื่อสร้างการตอบกลับ

## การโต้ตอบ
นอกเหนือจากการแบ่งโปรแกรมประยุกต์ออกเป็นส่วนประกอบเหล่านี้แล้ว การออกแบบ MVC ยังกำหนดการโต้ตอบระหว่างส่วนประกอบเหล่านั้นด้วย

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

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

## ดูเพิ่ม

## อ้างอิง

## บรรณานุกรม