MVVM คือสถาปัตยกรรมที่ถูกสร้างขึ้นมาเพื่อลดภาระความเหนื่อยล้าในการเขียนโค้ดสั่งงานหน้าจอที่เราเจอกันใน MVP ครับ
ใน MVP เรามี Presenter ที่ต้องคอยสั่ง View แบบละเอียดยิบ พอระบบใหญ่ขึ้น โค้ดสั่งงานพวกนี้จะยาวและน่าเบื่อมาก
MVVM เลยเอาเวทมนตร์ที่เรียกว่า Data Binding เข้ามาช่วยแก้ปัญหานี้ครับ โดยแบ่งการทำงานออกเป็น 3 ส่วนดังนี้:
- Model
ยังคงทำหน้าที่เหมือนเดิมทุกประการครับ คือจัดการกับข้อมูล การคำนวณ ติดต่อฐานข้อมูล หรือเรียก API โดยไม่สนใจหน้าจอเลย - ViewModel
หน้าที่ของมันคล้าย Presenter คือการดึงข้อมูลจาก Model มาเตรียมไว้ให้หน้าจอ แต่จุดที่ต่างกันโดยสิ้นเชิงคือ ViewModel จะ “ไม่รู้จัก View” เลยครับ มันไม่มีฟังก์ชันในการสั่งงาน View ไม่มีการจับคู่กันโดยตรง หน้าที่ของมันมีแค่เก็บ “สถานะ ” หรือข้อมูลล่าสุดของหน้าจอนั้น ๆ เอาไว้ เช่นcount = 0หรือisLoading = true - View
หน้าตา UI ของระบบ ใน MVVM ตัว View จะมีความฉลาดเพิ่มขึ้นมานิดหน่อยตรงที่มันสามารถ “ผูก “ ตัวเองเข้ากับตัวแปรใน ViewModel ได้
หัวใจสำคัญ: การทำงานของ Data Binding
ความมหัศจรรย์ของ MVVM อยู่ที่กลไกอัตโนมัตินี้ครับ เมื่อ View ผูกข้อมูลเข้ากับ ViewModel แล้ว
- ถ้าข้อมูลใน ViewModel เปลี่ยน: View จะอัปเดตหน้าจอตัวเองโดยอัตโนมัติทันที!
- ถ้าผู้ใช้พิมพ์ข้อมูลลงใน View: ข้อมูลใน ViewModel ก็จะถูกอัปเดตตามไปพร้อม ๆ กันแบบเรียลไทม์
เปรียบเทียบให้เห็นภาพง่าย ๆ
- MVP: Presenter ต้องสั่งงานว่า
document.getElementById ('text') .innerText = "Hello"; - MVVM: ViewModel แค่ประกาศตัวแปรว่า
this.text = "Hello";แล้วเดี๋ยวกลไก Data Binding ของ Framework จะเอาคำว่า Hello ไปแปะบนหน้าจอให้เองแบบอัตโนมัติ!
ตัวอย่างโค้ด Counter ด้วย MVVM
ลองเทียบกับโค้ด MVP ก่อนหน้านี้นะครับ จะเห็นว่าสั้นลงมหาศาล เพราะเราไม่ต้องเขียนโค้ดจับคู่ปุ่มหรือสั่งเรนเดอร์หน้าจอเองเลย
ฝั่ง View
<div id="app"> <h1>จำนวนปัจจุบัน: {{ count }}</h1> <button @click="increment">Add</button>
</div>
ฝั่ง ViewModel
// ViewModel แค่สนใจการจัดการ Data ตัวเอง ไม่มีการไปยุ่งกับ DOM เลย
const app = Vue.createApp ({ data () { return { count: 0 // เก็บ State } }, methods: { increment () { this.count++; // แค่บวกเลข เดี๋ยวหน้าจอ HTML จะอัปเดตเลขนี้เองอัตโนมัติ! } }
}) ; app.mount ('#app') ;
สรุปข้อดีหลัก ๆ ของ MVVM: โค้ดสั้นลงมาก, แยกการทำงานระหว่างคนทำ UI กับคนเขียน Logic ได้เด็ดขาด, และตัว ViewModel นำไปเขียน Unit Test ได้ง่ายสุด ๆ เพราะไม่มีโค้ดที่เกี่ยวกับหน้าจอ (DOM) ปนอยู่เลยครับ
อ่านเพิ่มเติม