Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

เมื่อ MVC ย่อมาจาก Massive ViewController

$
0
0

mvc

mvc เมื่อวานนั่งดู Code การพัฒนา iOS ด้วยภาษา Swift โจทย์เดียวกันจาก developer 4 คน แต่โครงสร้างของ code ที่ออกมานั้นเหมือนกัน นั่นคือเป็น MVC(Model View Controller) ในรูปแบบของ Apple ซึ่งส่วนใหญ่จะนำไปสู่ MVC ที่ย่อมาจาก Massive ViewController มากกว่านะ !! และนั่นคือความหายนะที่กำลังมาเยือนนักพัฒนาโดยทั้งรู้และไม่รู้ตัว

คำถามที่น่าสนใจคือ แล้ว MVC มันไม่ดีหรือไง ?

ตอบได้เลยว่าดีนะ ถ้าเข้าใจ และ ใช้งานได้อย่างถูกต้อง

คำถามต่อมา แล้วโครงสร้างแบบอื่นที่ดี ๆ ทำไมไม่ใช้กัน ?

ทั้ง MVP, MVVM และ VIPER เป็นต้น แต่ก่อนจะเลือกอะไรนั้น นักพัฒนาลองตอบคำถามเหล่านี้ก่อนสิ
  • เรื่องการการเรียกใช้งาน API ผ่านระบบ network ควรอยู่ตรงไหนดี Model หรือ Controller ?
  • จะทำการส่ง Model ไปยัง View เพื่อแสดงผลอย่างไร ?
  • ปัจจุบันเขียน code อย่างไร ?
  • ทดสอบกันแบบไหน ?
ถ้ายังงง ๆ ตอบไม่ถูก แสดงว่าอย่าเพิ่งทำอะไรเลยนะ มาทำความเข้าใจและเรียนรู้ จากนั้นมาฝึกฝนกันก่อน

คำถามต่อมา เราจะสนใจเรื่องโครงสร้างของระบบไปทำไม ?

ถ้านักพัฒนาไม่เลือกหรือกำหนดตั้งแต่แรก มันมักจะก่อให้เกิด class ขนาดใหญ่หรือ God class จำนวนมากมาย ยากต่อการค้นหาและแก้ไขอย่างมาก หรือแค่มานั่งไล่ code เพื่อทำความเข้าใจก็ยังยากเลย !! เรื่องของโครงสร้างมันก็สัมพันธ์กับความสามารถของทีมเช่นกัน

มาดูตัวอย่างจาก code ของ iOS app ที่พัฒนาด้วยภาษา Swift

จะมีลักษณะดังนี้
  • ทำการ extends มาจาก UIViewController
  • ข้อมูลต่าง ๆ ที่จะทำการแสดงผลหรือดึงข้อมูลจากภายนอกก็อยู่ใน UIViewController นี่แหละ
  • ส่วนของ UIViews ไม่ได้ทำอะไรเลย
  • Model ก็เป็นเพียง class และ struct สำหรับกำหนดโครงสร้างของข้อมูลเท่านั้น
  • UI testing อย่าคิด ส่วน Unit testing อย่าฝันว่าจะมี
ซึ่งเป็นผลมาจาก MVC ของ Apple นั่นเอง เมื่อเข้าไปดูเอกสารเรื่อง MVC จากทาง Apple แล้วพบรูปนี้ ซึ่งมันแจ่มมาก ๆ model_view_controller_2x

แต่เมื่อนำมา implement จริง ๆ กลับได้แบบนี้ !!

นั่นคือ ViewController ผูกติดกลายเป็นตัวเดียวกันไปเลย mvc-apple ซึ่งเป็นโครงสร้างที่เอื้อต่อการสร้าง Massive ViewController อย่างมาก เนื่องจากทำการรวม View Life Cycle เข้ากับ Controller ทำให้พวก business logic ต่าง ๆ รวมอยู่ในนั้นด้วย ทำได้เพียงแยกส่วนของ data หรือ Model ออกมาเท่านั้น ทำให้ใน ViewController นั้นจะใช้งานพวก Delegate และ Datasource ของทุก ๆ อย่างเสมอ เช่น TableView และ SwipeView เป็นต้น ผลที่ตามมาคือ View คุยกับ Model โดยตรง หรือ ทำการส่ง Model ไปให้ View ซะงั้น !! นั่นคือ ข้อขัดแย้งอย่างรุนแรงต่อ MVC และเราพบเห็นได้บ่อยมาก ๆ ใน ViewController ของ iOS app และนักพัฒนาทุกคนก็มองว่า มันเป็นเรื่องปกติ ไม่ได้ผิดอะไร !! เมื่อเวลาผ่านไปนานขึ้น ขนาดของ ViewController ต่าง ๆ ก็ใหญ่โตขึ้นเรื่อย ๆ นี่แหละคือที่ไปที่มาของ Massive ViewController ยังไม่พอนะ เมื่อต้องเขียน Unit testing ด้วยแล้ว !! ปัญหามันหนักมาก ๆ เนื่องจาก ViewController มันเยอะไปหมด code ผูกติดกันอย่างแน่นหนา ทั้ง View ทั้ง Controller ทั้ง Business logic หวังว่าระบบที่พัฒนาหรือดูแลกันอยู่ ไม่น่าจะเป็นเช่นนี้นะครับ

ดังนั้นสิ่งที่ควรทำก่อนเลยก็คือ

ทำความเข้าใจกับ code และลองเขียนออกมาหน่อยว่า ใน ViewController มีหน้าที่การทำงานอะไรบ้าง จากนั้นค่อย ๆ แยกส่วนการทำงานต่าง ๆ ออกมา โดยในแต่ละส่วนก็ช่วยเขียน Unit test ขึ้นมาคลุมหน่อยนะครับ ค่อย ๆ ถอด ค่อย ๆ แยก ค่อย ๆ ทดสอบ ค่อย ๆ integrate แล้ว code จะค่อย ๆ ดีขึ้นเอง

ส่วน code ใหม่ ๆ ลองคิด วิเคราะห์ แยกแยะก่อนว่า

ในแต่ละ feature ต้องทำอะไร ต้องการอะไรบ้าง โดยแนะนำให้ทำดังนี้
  • แยกส่วนการทำงานของ Model, View ออกจากกันก่อน
  • ส่วนของ Controller กับ View อาจจะยังติดกันนิดหน่อย
  • แต่ละส่วนการทำงานต้องสามารถทดสอบได้ แต่ถ้าคุณแยกส่วนการทำงานไม่ดีจะทดสอบได้ยาก หรือ ทำได้เพียง Model เท่านั้น ซึ่งต้องระวังให้มาก ๆ
  • Code แต่ละส่วนง่ายต่อการใช้งาน ง่ายต่อการดูแล แม้แต่นักพัฒนาที่มีประสบการณ์น้อยก็ตาม มิเช่นนั้นคุณจะเอาเทคนิคแปลก ๆ มาใช้จนคนในทีมงงไปเลย อย่าทำนะ !! มันจะเป็นการใช้งานที่มากเกินความจำเป็น
  • ของดีแต่อาจจะยังไม่เหมาะสมกับทีมในเวลานี้ก็เป็นได้
ดังนั้นการจะเลือกวางโครงสร้างของระบบอย่างไรนั้น มันมีปัจจัยหลาย ๆ อย่าง แต่เหนือสิ่งอื่นใด สิ่งที่คุณเลือกมันทำให้คุณและทีมช้าลงหรือเร็วขึ้น

Viewing all articles
Browse latest Browse all 1997

Trending Articles