สำหรับนักพัฒนาซอฟต์แวร์น่าจะผ่านตาคำว่า MVC มากันสักพักใหญ่แล้ว ผมเองก็เช่นกัน แต่ยังไม่ได้เริ่มศึกษาจริงจังเสียที แถมช่วงที่ดูแลงานจ้างพัฒนา ทางผู้พัฒนาก็ใช้คอนเซ็ปนี้ผ่าน PHP Framework ที่ชื่อ Laravel และ Codeigniter ส่วนตัวผมเองใช้แต่เครื่องมือของ Microsoft (Visual Studio) ซึ่งรองรับ MVC เช่นกัน จะมีโอกาสได้นำไปใช้พัฒนาจริงหรือเปล่ายังไม่รู้ แต่ก็ขอศึกษาและบันทึกความเข้าใจไว้ก่อน ต่อไปอาจมีความรู้อะไรใหม่ๆ มาต่อยอดจาก MVC อีก จะได้ไม่ตกขบวนจนเกินไปนัก 😆

MVC คืออะไร

MVC ย่อมาจากคำว่า Model-View-Controller เป็นหลักการออกแบบ (Design Pattern) แบบหนึ่งที่กำหนดมาตรฐานของการแยกส่วนของโปรแกรมออกเป็น 3 ส่วนหลัก คือ Model, View และ Controller

  • M-Model คือ ส่วนของข้อมูล มีหน้าที่จัดหาข้อมูล ตรวจสอบความถูกต้องของข้อมูล สถานะการเปลี่ยนแปลงของข้อมูล รวมถึง การบันทึกข้อมูลด้วย
  • V-View คือ ส่วนที่แสดงผลและโต้ตอบกับผู้ใช้ (User Interface) เช่น แบบฟอร์มนำเข้าข้อมูล หน้าจอแสดงผลลัพธ์ต่างๆ ซึ่งโค๊ดการทำงานส่วนนี้ทำหน้าที่เพียงควบคุมการแสดงผลเท่านั้น (Presentation Logic) นั่นคือ ไม่มีคำสั่งสำหรับติดต่อแหล่งข้อมูล หรือ SQL ในส่วนนี้เลย
  • C-Controller คือ ส่วนที่ทำหน้าที่รับคำสั่งการ (HttpMethod: POST(Create,C) GET(Read,R) PUT(Update,U) และ Delete(Delete,D)) พิจารณาว่าจะใช้ Model ใด และส่งต่อผลลัพธ์จากการทำงาน View ที่เกี่ยวข้อง เช่น หากประมวลผลสำเร็จให้ไปยังหน้า Success หรือมีความจำเป็นต้องกรองข้อมูลใหม่ก็ย้ายไปยังหน้าฟอร์ม

หลักการทำงานของ MVC (https://mva.microsoft.com/en-US/training-courses/introduction-to-asp-net-mvc-8322)

 

ทำไมจึงควรเปลี่ยนมาใช้ MVC

เมื่ออ่านแนวคิดของ MVC ข้างต้นแล้ว ผมก็มาคิดทบทวนว่าระบบที่เราพัฒนากันอยู่มันเป็นปัญหายังไง

  • ช่วงหลังพัฒนางานด้วย ASP.NET แบบ Web Form ทำการสร้าง Page (.aspx) จัดวาง Control ต่างๆ เมื่อเกิด Event ก็เรียกการทำงานที่เขียนอยู่ใน Code-Behind (.vb หรือ .cs) บางคนไปเขียดโค็ตแบบ In-line ใน Page ตรงๆ เลยก็มี แบบนี้ หน้าจอ และ กระบวนการทำงาน (Logic) จะผูกติดกันแน่น (เขียน Window Form ก็ไม่ต่างกัน) แถมบาง Logic ยังเกิดซ้ำๆ ใน Page อื่นอีก เมื่อจำเป็นต้องแก้ไข ก็ต้องมาว่าโค็ตอยู่ที่ไฟล์ไหนบ้าง แก้แบบ Copy-Paste กัน
  • ในระยะต่อมาได้แยก Logic ออกมาอีกชั้น เขียนเป็น Module หรือ Class เพื่อให้สามารถใช้ซ้ำๆ กันได้หลายที่ การแก้ไขก็ก็สะดวกขึ้น ทิ้งให้ Code-Behind ควบคุมส่วนแสดงผลเป็นหลัก
  • สำหรับสาย PHP นั้น ผมไม่ได้ไปยุ่งเกี่ยวมากนัก แต่ก็เคยเห็นโค็ดงานมาบ้าง ในไฟล์ .php เต็มไปด้วย โค๊ด html แทรกด้วย php แบบ In-line เป็นระยะๆ ยิ่งตอนวนลูปนี่ทำเอาผมที่ไม่ชินถึงกับงงไปเลย บางทีก็เรียก include มาจากไฟล์อื่น เมื่อต้องแก้ไขคงมึนไม่ต่างกัน
  • สำหรับการติดต่อกับฐานข้อมูล พบว่าใน Page หรือ Code-Behind จะสร้างการเชื่อมต่อและฝัง SQL เอาไว้เลย ได้ข้อมูลมาแล้วก็ประมวลผล แล้วไปแสดงในหน้าจอ ไม่อยากคิดถึงตอนแก้ไขเลย ยิ่งถ้าต้องย้ายฐานข้อมูลด้วยแล้ว คงวุ่นน่าดู ไม่ต้องพูดถึงเรื่องทดสอบนะ…สาหัส!!!!
  • เมื่อเจอปัญหาต่างๆ ทีมวิเคราะห์โครงสร้างระบบก็คิดกันใหญ่เลย แบ่งชั้นแบบนี้นะ แบบนั้นนะ ตามความรู้ในล่ะยุค นั่นคือโครงสร้างของโปรแกรมอาจไม่เป็นมาตรฐานนั่นเอง การส่งต่องานจึงยากไปด้วย

ทั้งนี้การพัฒนาระบบแบบเดิมนั้นมีข้อดีในเรื่องของความเร็วในการพัฒนา เริ่มต้นได้เร็ว ผู้ให้ความต้องการหรือแม้แต่ผู้พัฒนาเองก็สามารถเห็นหน้าจอที่สามารถคุยกันง่าย อยากให้ปุ่มไหนทำอะไรก็จิ้มแล้วลงมือเขียนโค๊ดได้ แต่ในระบบที่มีผู้พัฒนาหลายคน ระบบขนาดใหญ่ขึ้น หรือระบบที่ต้องการการขยายตัวได้ การพัฒนางานแบบเดิมที่ทุกอย่างถูกผูกติดกันอย่างเหนียวแน่น นั่นยากต่อการเพิ่มเติม แก้ไข และทดสอบ ดังนั้น Design Pattern เหล่านี่จึงถูกนำเสนอขึ้นมา เช่น MVC (Model-View-Controller) MVP (Model-View-Presenter) และ MVVM (Model-View-ViewModel) เป็นต้น โดยมีแนวคิดที่จะแบ่งงานออกมาส่วนๆ ที่เป็นอิสระต่อกันหรือผูกกันหลวมๆ ซึ่งมีมีส่วนที่เหมือนหรือต่างกันอย่างไรนั้นคงต้องหาจังหวะเวลาศึกษาต่อไป 😆 แต่ตอนนี้งานในการดูแลจากการจัดจ้างต่างก็ใช้ MVC เป็นหลัก และ ASP.NET ก็รองรับ MVC และตอนนี้พัฒนามาจนถึงรุ่น 5 แล้ว ก็คงต้องทำความเข้าใจ MVC ก่อน เดี๋ยวจะตกขบวนไปไกล

สรุปความเข้าใจสั้นๆ ว่าถ้าเราใช้ MVC ชีวิตนักพัฒนามันจะดีขึ้นยังไงบ้าง

  1. โปรแกรมที่พัฒนามีโครงสร้างเป็นมาตรฐาน โค๊ดไฟล์เป็นระเบียบ แยกโค๊ดส่วน ประมวลผลข้อมูล ออกจาก การแสดงผล อย่างชัดเจน
  2. สามารถทดสอบการทำงานได้ง่าย (Unit Test)
  3. หากมีความจำเป็นต้องเปลี่ยนแปลงระบบจัดเก็บข้อมูลก็จะแก้ไขที่ Model หรือ Service ที่ทำงานกับข้อมูล
  4. หากมีความต้องการปรับ User Interface ใหม่ ก็สามารถแก้ไขที่ View โดยไม่กระทบกับส่วนอื่น
  5. เมื่อเงื่อนไขหรือกระบวนการทำงานเปลี่ยนไป แก้ไขเฉพาะ Controller เท่านั้น (เว้นแต่เป็นการเปลี่ยนแปลงถึงโครงสร้างข้อมูล อาจกระทบทั้ง M-V-C เลย)

MVC Variations

เมื่อหาข้อมูลไปเรี่อยเราจะยังพบว่า MVC Pattern ยังแบ่งย่อยออกเป็น 2 รูปแบบอีก (เอาเข้าไป) คือ Passive Model และ Active Model

Passive Model

รูปแบบนี้ Model จะอยู่นิ่งๆ เฉยๆ เป็นอิสระจาก Controller และ View เมื่อข้อมูลเกิดการเปลี่ยนแปลง Controller มีหน้าที่แจ้งไปยัง View เท่านั้น และ View จะร้องขอข้อมูลใหม่มาใช้งาน

Behavior of the passive model (https://msdn.microsoft.com/en-us/library/ff649643.aspx)

Active Model

ในรูปแบบนี้ เมื่อ Controller ทำให้ Model เปลี่ยนไปจากเดิม Model มีหน้าที่ในการแจ้งการเปลี่ยนแปลงนี้ให้กับ View ได้รับรู้ และร้องขอข้อมูลใหม่มาใช้งาน

ซึ่งวิธีนี้ Model จะต้องรู้ว่าตัวเองถูกใช้ใน View ใด ก่อนให้เกิดการผูกติดขึ้นมา ขัดต่อแนวคิดเริ่มต้นของ MVC ที่ต้องการให้ Model และ View เป็นอิสระต่อกัน ในแผนภาพข้างบนได้แสดงให้เห็นว่าได้นำ Observer Pattern มาใช้งาน (อารมณ์เหมือน Publisher-Subscriber แบบ 1-to-many ถ้าอยากรู้ข่าวสารก็ไปลงทะเบียนกับ Publisher ซะ) นั่นคือ จะมีการลงทะเบียน View กับ Model เพื่อให้รู้ว่าเมื่อเกิดการเปลี่ยนแปลงจะแจ้งให้กับ View ในลิสต์ที่ลงทะเบียนไว้

Using Observer to decouple the model from the view in the active model (https://msdn.microsoft.com/en-us/library/ff649643.aspx)

Behavior of the active model (https://msdn.microsoft.com/en-us/library/ff649643.aspx)

 พออ่านไปหลายๆ บทความได้พบว่าแก่นหลักๆ น่าจะพยายามให้นักพัฒนาแยกงานส่วน หน้าจอ (View) กับ ส่วนประมวลผล (Logic/Model) ออกจากกัน โดยมี Controller เป็นตัวกลางในการจัดการให้ View และ Model มาเจอกัน ส่วนรายละเอียดปลีกย่อยจะมีแตกต่างกันบ้างจนทำให้มึนได้ เอาเป็นว่ามาเริ่มเปิด Project ASP.NET MVC ใน Visual Studio กัน

ASP.NET MVC Web Application

คราวนี้ลองมาสร้าง Project แบบ MVC ดูบ้างว่า ASP.NET จัดโครงสร้างงานออกมายังไง ซึ่งการ New Project ใน Visual Studio ในแต่ละรุ่นอาจไม่เหมือนกัน เอาเป็นว่า ถ้าไม่เห็น ASP.NET MVC ที่หน้า Template หลักของ Web ให้คลิกที่ ASP.NET Web Application เลือก MVC หรือ Empty ก็ได้ แต่ให้เลือก MVC ที่ Add folder and core references ผมตั้งชื่อ Project ว่า HelloMVC แบบ No Authentication แอบติด Unit Tests มาด้วย (ไว้ศึกษาต่อคราวหลัง)

 

โครงสร้างของ Project จากการสร้างด้วยต้นแบบ MVC หรือ Empty MVC ก็มีโครงสร้างเหมือนกัน คือ มีโฟล์เดอร์แยกสำหรับ Controllers Models และ Views เหมือนกัน ต่างกันตรงที่มีไฟล์ตั้งต้นติดมาให้ นอกจากนี้ใน ASP.NET MVC จะมีไฟล์ RouteConfig.cs (ถูกเรียกใช้ผ่าน Global.asax) สำหรับจัดการคำร้องขอให้ไปยังเส้นทางที่กำหนด ซึ่งในรูปแบบ MVC คือการระบุไปยัง Controller นั่นเอง

สร้างจาก MVC Project

สร้างจาก Empty Project

 

เมื่อ User ระบุเส้นทางผ่าน URL บน Browser ตัว HttpRequest นั้นจะถูกส่งมายัง Routing Engine ซึ่งใน Default Route ได้กำหนดให้เลือกตาม ชื่อ Controller ต่อด้วยคำสั่ง Action และ ID (ถ้ามี) เช่น http://<server:port>/Home/Index จะเข้าตามข้อกำหนด นั่นคือไปเรียก HomeController และ Action ชื่อ Index ซึ่งใน Action จะส่ง View() ไปให้ User นั่นคือ View ที่ตรงตามชื่อ Controller/Action ในโฟล์เดอร์ View นั่นเอง

 

จากตัวอย่าง MVC ที่ Visual Studio เตรียมให้เรามานั้น ทำให้ผมเห็นภาพเพียงบางส่วนเท่านั้น คือ การทำงานจะอาศัย Routing Engine เพื่อเลือกใช้ Controller ที่ต้องการ ยังคงเหลือส่วนของ Model ใน ASP.NET MVC ว่าคืออะไร คงต้องยกไปในบันทึกถัดไป สำหรับบันทึกเอกสารฉบับนี้หากมีข้อผิดพลาดหรือขอแนะนำอย่างไร Comment ไว้ข้างล่างเลยครับ

อ้างอิง

http://www.w3ii.com/th/asp.net_mvc/default.html

https://mva.microsoft.com/en-US/training-courses/introduction-to-asp-net-mvc-8322?l=nKZwZ8Zy_3504984382

https://www.arnondora.in.th/what-is-mvc/
http://www.kontentblue.com/site/article/article.php?id=mvc-what-is

http://www.pisit.in.th/php/mvc

https://msdn.microsoft.com/en-us/library/ff649643.aspx

https://www.codeproject.com/articles/674959/mvc-patterns-active-and-passive-model-and-its

http://www.codeproject.com/Articles/661878/Implementation-of-MVC-Patterns-in-ASP-NET-Web-form

 

ลืม password เข้าเครื่อง Mac
ย่อลิ้งค์ยาวๆ ให้สั้น พร้อมทำ QR โค้ด และตรวจสอบจำนวนครั้งที่ลิ้งค์ถูกคลิ๊ก ด้วย "goo.gl"

Leave a Comment