MVC คืออะไร?
![](/site/image/Calendar_Icon.png)
Use Cases และตัวอย่าง
อ่านมาตั้งนานพอเห็นเค้าลาง MVC บ้างไหมครับ ถ้าพอเห็นลางๆแล้วก็มาเติมเต็มด้วยตัวอย่างกัน การทำแอพพลิเคชันโดยทั่วไปคงหนีไม่พ้นงานที่เกี่ยวข้องกับ CRUD Operations ซึ่งก็คือ
- Create (C)
- Retrieve (R)
- Update (U)
- Delete (D)
โอเปอเรชันเหล่านี้ก็คือโอเปอเรชันที่เกี่ยวข้องกับข้อมูลนั่นเอง จะ Create ด้วยเงื่อนไขไหนจะ Retrieve ด้วยโลจิกอะไร ก็แล้วแต่แต่ละธุรกิจกันไป ร้านหนังสือก็เงื่อนไขนึง ธนาคารก็อีกเงื่อนไขนึง แต่ยังไงมันก็หนีไม่พ้นเจ้า CRUD นี่แหละ ดังนั้นพอจะออกแบบออบเจกต์ก็หนีไม่พ้น MVC+S เช่นกัน ในเมื่อมันต้องมีข้อมูลมันก็คือ Model, CRUD ก็คือโอเปอเรชันใน Service, แล้วมันก็ต้องมีส่วนแสดงผลใช่ไหมครับ มันก็คือ View, และสุดท้ายตัวรับคำสั่งก็ต้องมีซึ่งมันก็คือ Controller สั่งให้ค้นหาก็ต้องทำการ Retrieve ไม่ใช่ไปทำ Delete โอเปอเรชัน ถูกไหมครับ เอาหล่ะผมจะยกตัวอย่างผ่าน Use Cases ง่ายๆดังนี้นะครับ สมมุติว่าเราต้องการบริหารจัดการข้อมูลพนักงานดังแสดงในรูปที่ 5 คือต้องสามารถเพิ่มข้อมูลเข้าไปในระบบได้ และสามามารถดึงข้อมูลทั้งหมดขึ้นมาดูได้
![](/site/image/article/mvc/UseCase.png)
ในการออกแบบและวิเคราะห์เราจะไล่ทำกันทีละ Use Case แต่ละ Use Case เราก็จะมาวิเคราะห์กันว่าน่าจะมีออบเจกต์อะไรบ้าง ถ้านึกไม่ออกก็ MVC+S นั่นเอง ดังนั้นใน Use Case ของการเพิ่มข้อมูล เราจึงสามารถออกแบบออบเจกต์ได้ดังแสดงในรูปที่ 6 ซึ่งจะเห็นได้ว่า:
- จุดเริ่มต้นนั้นมาจากการกรอกข้อมูลในฟอร์ม View
- เมื่อผู้ใช้กรอกข้อมูลเสร็จกดปุ่มส่ง ข้อมูลก็ถูกส่งไปยัง Controller
- Controller มีหน้าที่ในการดึงข้อมูลขึ้นมาและตรวจสอบความถูกต้องก่อน (หากพบว่าไม่ถูกต้อง ก็ต้องส่งหน้าฟอร์มกลับไปให้กรอกใหม่)
- จากนั้น Controller จึงเปลี่ยนข้อมูลให้อยู่ในรูปของ Model พร้อมประมวลผล และเรียกใช้ Service
- เมื่อ Service ตอบผลลัพธ์กลับมาจึงทำการเรียก View ให้แสดงผลลัพธ์ตอบกลับ (อาจเป็นได้ทั้งกรณีที่สำเร็จหรือไม่สำเร็จก็ได้)
![](/site/image/article/mvc/AddNew.png)
เป็นอันจบไปหนึ่ง Use Case ตัวอย่างที่ 1 ข้างใต้นี้แสดงโค้ดแบบคร่าวๆของ AddEmployeeServlet เพื่อให้เห็นว่า Controller มีการเรียกใช้ Service และส่งต่อ View อย่างไร
public class AddEmployeeServlet extends HttpServlet{
public void doPost(HttpServletRequest request,HttpServletResponse response){
String name = request.getParameter("name");
String phone = request.getParameter("phone");
String email = request.getParameter("email");
. . .
//perform some validation
if(phone.length() < 9){
// do something
}
// if validation succeeds
Employee emp = new Employee();
emp.setName(name);
emp.setPhone(phone);
emp.setEmail(email);
. . .
EmployeeService service = new EmployeeService();
boolean status = service.addNew(emp);
if(status == true){
RequestDispatcher rd = request.getRequestDispatcher("/Confirmation.jsp");
rd.forward(request,response);
}
} // end of doPost()
} // end of class
ทีนี้มาลองดู Use Case สุดท้ายบ้างนั่นก็คือการดึงข้อมูลทั้งหมดขึ้นมาดู ซึ่งก็สามารถออกแบบได้ดังแสดงในรูปที่ 7 โดยมีรายละเอียดดังนี้:
- เริ่มต้นผู้ใช้ส่งรีเควสต์เข้ามายัง Controller ได้เลย โดยสามารถคลิกลิ้งค์จากเมนูได้ทันที (ทำให้ Use Case นี้ไม่มี View ที่เป็น Input)
- จากนั้น Controller จึงเรียกใช้ Service เพื่อขอข้อมูลผลลัพธ์ ซึ่งก็คือ List ของ Employees (Model) ทั้งหมด ในขั้นตอนนี้ออบเจกต์ Service จะต้องเปลี่ยนข้อมูลดิบให้อยู่ในรูปของ Model
- เมื่อได้ผลลัพธ์มาแล้วจึงทำการส่งผลลัพธ์นั้นไปยัง View เพื่อให้ View นำไปใช้แสดงผล
![](/site/image/article/mvc/GetAll.png)
จะเห็นได้ว่าไม่ว่า Use Case ไหนๆก็หนีไม่พ้น MVC+S ใช่ไหมครับ เพียงแต่จะมี M,V,C,S อย่างละกี่ตัวก็เป็นอีกเรื่องนึง อ้อแล้วบางตัวก็ใช้ข้าม Use Case กันได้นะครับอย่างเช่น EmployeeService และ Employee เป็นต้น
(หากคุณไม่ถนัดภาษา Java และในภาษาที่คุณใช้ไม่มีคำสั่ง forward() ก็ไม่ต้องตกใจนะครับ คุณก็ใช้คำสั่ง include() แทนได้ - แต่ Servlet ก็มี include นะ!!! และบาง MVC Frameworks ก็บังคับให้รีเควสต้องวิ่งเข้า Controllers เสมอ จะไม่ยอมให้เข้า Views โดยตรงได้ ก็มีนะครับ แต่หลักใหญ่ใจความก็เหมือนๆกัน )
บทสรุป
เป็นอย่างไรกันบ้างครับอ่านกันมายาวพอสมควร ผมสรุปให้ดังนี้นะครับ การเขียนโปรแกรมแบบ OOP ก็คือการแบ่งแอพพลิเคชันออกเป็นออบเจกต์ย่อยๆ ซึ่งการแบ่งนี้เรานิยมแบ่งตามบทบาทหน้าที่ของออบเจกต์ และเรานิยมแบ่งออกเป็น M,V,C + S ซึ่งเรียกได้ว่าเป็นบทบาทพื้นฐานที่มีในทุกๆแอพพลิเคชันได้เลย การแบ่งแบบนี้ก็เพื่อที่จะให้การเปลี่ยนแปลงแก้ไขทำได้ง่ายขึ้นในอนาคต อีกทั้งหากเป็นระบบใหญ่ที่มีความซับซ้อน ต้องทำงานกันหลายคนเป็นทีม เรายังสามารถแบ่งงานกันตามบทบาทหน้าที่ของออบเจกต์ได้อีก เช่นว่า ถ้าเราถนัด Servlet/JSP เราก็รับในส่วนของ C และ V ไป ใครถนัด JDBC ก็รับ S แถม M ไป ใครรู้กว้างก็เป็นคนวิเคราะห์ออกแบบระบบ นอกจากนี้เรายังสามารถประยุกต์ใช้ Design Patterns ตัวอื่นๆร่วมได้อีก อาทิเช่น DAO, Business Delegate เป็นต้น ทั้งนี้ทั้งนั้นต้องขึ้นอยู่กับความเหมาะสมด้วย ไม่ใช่ยิ่งเยอะแล้วจะดี แต่ยังไงก็แล้วแต่ MVC+S คือพื้นฐานสำคัญที่ควรมีในทุกๆแอพพลิเคชัน แม้จะไม่ใช่เว็บแอพพลิเคชันก็ตาม แถมอีกนิดนึง ใน Java หากเป็นเดสก์ท็อปแอพพลิเคชัน V และ C จะเป็นอะไรครับ? V ก็คือ Swing ส่วน C ก็คือ Listener นั่นเอง เวลาผู้ใช้กดปุ่ม Listener ก็ถูกเรียกให้ทำงาน ซึ่งก็จะไปเรียกตัว S อีกที เห็นมั๊ยครับมันก็ MVC+S นั่นเอง (ไม่ใช่ไปฝั่ง Business Logic และ Data Access Logic ลงไปใน Listener มิเช่นนั้นจะนำมันกลับมาใช้ใหม่ได้อย่างไร) โอกาสถัดไปจะเขียนถึงหลักการ OOAD และ UML บ้างนะครับ