MVC vs FLUX เมื่อ Front-end กลายเป็น Non-manageable Applications

เป็นเวลานานมากที่เราเขียนโปรแกรมกันมาด้วยแนวคิดที่เรียกว่า MVC ไม่มีใครไม่รู้จัก หรือแทบจะไม่มีโปรแกรมไหนในโลกที่ไม่ใช้ MVC ในการเขียนโปรแกรม พักหลังๆ ผมเริ่มจะเขียน ReactJs แบบจริงจัง ตอนนี้ก็เริ่มศึกษา Redux อยู่ จู่ๆ ก็ไปสะดุดกับหลายๆ บทความของฝรั่งที่เขาพูดถึง MVC และ FLUX กันเยอะมาก กะว่าจะเขียนรวบยอดรีบเรียงในความเข้าใจมาให้อ่านกัน

เอาละเรามาเข้าเรื่องกัน MVC (Model View Controller) คืออะไร? …….ใครยังไม่รู้กดลิ้งไปอ่านบทความเก่าผมก่อน กด

บทความนี้ผมจะมาพูดถึงเทคโนโลยี Front-end กันโดยเฉพาะ เพราะจะมาอธิบายปัญหาที่เกิดขึ้นกับ Web Developer โดยเฉพาะคนที่ทำ Front-end รวมถึงตัวผมด้วย ปกติผมเองทำทั่ง Back-end, Front-end มาตลอดตั่งแต่สมัยเรียน รวมๆ แล้วก็หลายปีอยู่ ก็ได้เจอปัญหามาพอสมควร เห็นความแตกต่างมาพอสมควร ก่อนจะอธิบายปัญหาที่แท้จริง ผมขออธิบายสิ่งที่จำเป็นต้องรู้และยกตัวอย่างก่อนทีละหัวข้อนะครับ

Use-case

ระบบเรามี user อยู่ 2 role (Admin, Staff) ปัญหาคือเราใช้ View ตัวเดียวกัน (reuse view) ในการแสดงข้อมูล และเช็คค่าต่างๆ (controller) ว่าแต่ละ role ต้องการแสดงข้อมูลอะไร (model / state) ถ้าเกิดเราเพิ่ม requirement เข้าไป เพิ่มฟังก์ชันการทำงาน (เริม scale ระบบ) เราจะพบว่ามันจะกะทบการแสดงผลของ role แต่ละ role ซึ่งทำให้เราต้องคำนวณ logic ใหม่ เพื่อรองรับ data แบบใหม่ แถมยังต้อง reuse view เดิม พอเห็นภาพไหมครับ ? ทำให้การ scale ระบบยากมาก พอดีไปสะดุดสไลด์พี่คนนี้เข้า น่าสนใจทีเดียวก็เลยจะมาอธิบายให้ฟัง

 

Client-Side MVC

ถ้าเราพูดถึงเรื่องของ Framework ของสาย Front-end ยกตัวอย่างคราวๆ ที่นำ MVC มาประยุกต์ใช้หลักๆ เลยก็คือ Angular, Ember, Backbone, Polymer, Knockout คราวๆ ประมาณนี้ (คิดไม่ออกเยอะมาก) ซึ่งจริงๆ แล้วการที่เอา MVC มาใช้เนี่ยเพื่อแยกการทำงานของโค้ดแต่ละส่วน 1. data (Model) 2. presentation (View) 3. logic (Controller) เพื่อมาประกอบกันเป็นโปรแกรม 1 ตัว แต่มันก็นำปัญหามาให้เหมือนกันครับ นั่นคือ 1. การทำงานของ data flow มันเป็น bidirectional (ทำงานสองทิศทาง) แบบที่ยกตัวอย่างประกอบไป และ 2. การอัพเดทข้อมูลเกิด Sided-effect กับหลายไฟล์ (Cascading update)

1

ถ้าเราเอา usecase ที่ผมยกตัวอย่างมาเทียบกับรูปด้านบนเราจะเห็นว่าการทำงานของ front-end ค่อนข้างซับซ้อน ไม่ต้องพูดถึงการ scale นะ แค่ภาพก็บอกได้แล้วว่าผลจะเป็นยังไง

 

Server-Side MVC

เราลองมาดูการทำงาน MVC กันก่อน ตามแบบฉบับของ Smalltalk-76 (ต้นกำเนิด MVC ปี 1970) ซึ่งผมจะยกตัวอย่างการทำงานของ Back-end Framework ให้ดู ปกติแล้วสมัยนี้ (จริงๆ ก็มีมานานแล้ว) เขาจะมี pattern ในการออกแบบโครงสร้างระบบหลักๆ เลยคือ Model ,Controller, Route , View

  • ผู้ใช้งานเปิดบราวเซอร์ แล้วพิมพ์อะไรสักอย่างบนหน้าเว็บ และส่งข้อมูลมาผ่าน Route (URL Server) ที่เราประกาศไว้ในฝั่ง Back-end เพื่อเข้ามาขอข้อมูล (HTTP Request)
  • Back-end ทำการเช็คว่า Route (URL) ที่ผู้ใช้งานเรียกมา นั่นผูกอยู่กับ Controller (Logic) ตัวไหนและทำการส่งค่าเข้าไปประมวลผล
  • เมื่อ Controller ได้รับค่าแล้วก็ทำงานตามกระบวนต่างๆ ที่เราเขียนไว้เพื่อติดต่อกับ database (Model)
  • เมื่อคำนวณผลเสร็จก็ทำงานส่งค่ากลับไปหาผู้ใช้งาน (View) ที่บราวเซอร์ (HTTP Response)

2

เราจะเห็นว่ากระบวนการทำของ Framework ของ sever จะตรงไปตรงมา คือ URL ผูกกับ Controller , Controller ผูกกับ Model ซึ่งการทำงานมักจะเป็น 1:1 ทำให้การทำงานไม่ซับซ้อนเป็นการทำงานแบบ unidirectional

 

Introduce “State” in application

เดียวนี้เราจะได้ยินกันบ่อยๆ กับคำว่า state เช่น เก็บ state , ออกแบบ application แบบ stateless เป็นต้น แล้ว state คือะไร ? จริงๆ แล้ว state มันก็คือข้อมูล (data) เช่นเราทำหน้าเว็บเพื่อรองรับการแสดงผลข้อมูลต่างๆ ซึ่งข้อมูลต่างๆ มันก็คือ state

บางคนอาจจะได้ยินว่า state มันคือสถานะ พูดแบบนั่นก็ไม่ผิด ทำไมน่ะหรอ ถ้าเรากด checkbox เราจะได้สถานะ checked ใช่ไหม? แล้ว checked มันคืออะไร? มันก็คือ true / false นั่นแหละครับ แล้ว true / false มันคือข้อมูลไหม? ถ้าใช่ แล้วมันก็คือ state ใช่ไหมครับ?

ใน MVC อะไรคือ state?  มันก็คือ database(Model) ไงยังครับ แหล่งเก็บข้อมูลนั่นเอง อย่างเช่นเวลาเราส่งข้อมูลมาเพื่อเก็บอะไรลง database สักอย่าง แล้ว database ก็เก็บสถานะข้อมูลอันนั่นให้เรามันก็จะเป็นการทำงานเหมือนรูปข้างบน

 

Side-effice update

มาถึงตรงคงจะพอเข้าใจการทำงานแบบ bidirectional กันแล้วในหัวข้อที่ผ่านมา เรายังเหลืออีกปัญหานึงคือ เมื่อมีการเปลี่ยนแปลงข้อมูล (Model / State) จาก ณ จุดใด จุดนึงของระบบ ทำให้เกิด ผลที่ตามมา (Side-effice) กับ view หรือ controller ที่เราไม่ได้แก้ ดูจากรูปจะเห็นจุดเชื่อมกันอยู่มากเลย ถ้ากล่อง Data เปลี่ยนแปลง ผลที่ตามก็มีดังรูปเลยครับ

Screen Shot 2559-07-28 at 12.48.21

จากรูปเราสรุปได้ว่า

  • View เข้าไปทำงานกับ Model โดยตรง ตามหลักการแล้วต้องผ่าน Controller เท่านั่น
  • Model เก็บข้อมูลของ View หลายตัวพร้อมๆ กัน
  • Model กับ View ทำงานซ้อนกันมีการเอา state มาเก็บไว้ใน View ด้วย

สำหรับ Application ขนาดเล็ก MVC ไม่ค่อยมีปัญหาอะไรมากมันยังเป็นสิ่งที่จำเป็นต้องใช้อยู่ และมันยังควบคุมและดูแลรักษางานง่ายๆ แต่ถ้าเป็น Application ขนาดใหญ่ละ ? ….. จากรูปทั่งหมดคุณคิดว่าไง?

 

What is a FLUX  Pattern

ผู้ให้กำเนิดแนวคิดการทำ Front-end แบบ one-diection เลยก็คือ Facebook เพราะเขาเองก็เจอปัญหาแบบคือ ไม่สามารถ scale ระบบจาก codebase ของเขาได้ เขาเลยคิดใหม่ พร้อมกับออก ReactJS มาเพื่อการแก้ปัญหา MVC นั่นเองครับ โดยส่วนประกอบของ FLUX จะมีดังนี้

  • Actions – เหมือนเป็นตัวช่วยให้ส่งค่า และไปยังตัวรับหน้าที่ในการคำนวนผล ตัวอย่างเช่นเรากดปุ่มส่งค่าไป ตัว Action ที่ผูกอยู่กับ View จะทำหน้าที่เอาข้อมูไปส่งนั่นเอง (มันทำหน้าที่เก็บ property กับ data ไว้ในตัวมันด้วย)
  • Stores – เป็นตัวเก็บ application state กับ logic โดยเมื่อคำนวณผลเสร็จมันก็จะส่งไป View เพื่อแสดงค่า
  • Dispatcher – ตัวนี้มันตัวคั่นกลางของ Action เมื่อเกิด Action ตัว Dispatcher จะเป็นคำนวนว่าจะส่งข้อมูลไปให้ Stores ที่ผูกกับ Action ตัวไหนเพื่อประมวลตาม logic
  • Views – ตัวนี้ก็ไม่ต้องอธิบายเยอะมันก็คือ View นั่นแหละครับ ที่ผูกกับ Stores  เมื่อมีการเปลี่ยนแปลงอะไรใน Stores ตัว View ก็จะไปดึงเอาข้อมูลมาแสดงผลในตัวมัน (real time นะ)

สรุปคือ Views ผูกกับ Actions,  Actions ผูกเช็คโดย Dispatcher ก่อนส่งข้อมูล, Stores ผูกกับ Dispatcher และ Views ปลายทางผลลัพธ์

ซึ่งมันทำให้ Side-effect ที่พูดไปหัวข้อบนหมดไปเพราะ แต่ละ View เราะจะมี Dispatcher, Stores, Actions ของมันเองนะครับ อะไรทำนองนั่นครับ

 

Evolution of FLUX to MVC

เป้าหมายของ FLUX คือการทำงานแบบ one-diection/unidirection ดังนั่นเราจะมาเปลี่ยนการทำงานใหม่ให้เป็น

Screen Shot 2559-07-28 at 14.06.59

เมื่อเราปรับปรุงเป็นการทำงานแบบ one-diection  แล้วและเป้าหมายต่อไปสร้าง  Stores ไว้เก็บ Logic กับ Data ฟังดูเหมือน Controller แต่ทำไมมี Data ด้วยละ … Data มันของ Model นิน่า?????? 

Screen Shot 2559-08-01 at 12.56.23

เมื่อหัวข้อบนผมอธิบายไปว่า Stroes เก็บ Data กับ Logic ไว้จำได้ไหมครับ นั่นละครับ Facebook เขาเลยเอามามารวมกันแล้วเรียกมันในชื่อใหม่นั่นเอง และยังอยู่ในแนวคิดของ one-diection ที่นี้เรามาพิจารณา รูปข้างบนอีกทีเราจะเห็นอะไรไหม side-effect update กลับมาครับ

Screen Shot 2559-08-01 at 12.58.56

 

มาลองวิเคราะห์กัน View (สีฟ้า) เรียกไปหา Store (สีเหลือง) ผลคือ สีฟ้าเรียกก็จริง แต่ View (สีแดง) ดันติดผลไปด้วยนั่นเองครับ สรุปก็ไม่ต่างไรกับ MVC เลย ดั่งนั่นเรามาดูต่อว่า Facebook เขาแก้มันยังไง

ลองดูรูปข้างล่างครับ เขาก็สร้างตัวกำหนดเงือนไขมา ก็คือ Dispatcher นั่นเอง เหมือนบอกว่าคุณมาจากไปไหน คุณต้องไปไหนเอง ดูภาพแล้วเคลีย์ขึ้นไหมละครับScreen Shot 2559-08-01 at 13.10.14

ที่นี้ลองมาดูภาพรวมของระบบ เมื่อเราเอา Back-end และ Front-end มาทำงานต่อกับเป็น 1 โปรแกรม

Screenshot from 2016-08-01 22:05:34

 

ถึงตรงนี้เข้าใจหรือยังครับ ว่าถ้าเราใช้ MVC ต่อเราจะวางโครงสร้างระบบยังไงดี เพือไม่ให้เกิดปัญหาในการบำบุงรักษา จากภาพข้างบนผมคิดว่าทุกคนคงร้อง….อ่อกันแล้วนะครับ (หวังว่างั่น)

 

Summery

สรุปจากที่เราอ่านมาทั่งหมด ผมไม่ได้สอนเขียนโค้ดแม้แต่ตัวเดียว เราจะมาพูดแค่แนวคิดกับปัญหาเท่านั่นเอง เพราะจริงๆ แล้ว Flux ที่ออกมาพร้อมกัน ReactJS ที่ Facebook ออกมาให้เราใช้มันเป็นแค่ “ทฤษฏี” ที่ให้เราเอาไปต่อยอดเฉยๆ แต่จริงๆ แล้ว ReactJS มีไลบรารี่ของ Flux ที่ Facebook ทำออกมานะครับ แต่เขาบ่นกันว่ามันยากไป ซับซ้อนไปจึงมีคนเอาแนวคิดที่ Flux ที่ว่ามาไปทำ Redux แทนไงครับ

แล้ว ReactJS คืออะไร จริงๆ Facebook ต้องการแก้ปัญาหาและนำเสนอการทำงานแค่ฝั่ง Client นะครับ จะเห็นว่าหลายเว็บ หลายๆ คนจะพูดว่า ReactJS มีแต่ View ไม่สามารถทำอะไรได้นอกจากแสดงผล (ผมอาจจะผิดก็ได้แต่เท่าที่ลองอ่านและทำมามันมีแค่นี้จริงๆ ) และ Facebook ก็ยังรักษาความเป็น MVC ไว้คือให้ M กับ C ไปอยู่บน Server แบบที่มันควรจะเป็นและเอา ReactJS มาทำเป็น V ด้วยไม่เอา MVC มาไว้ในส่วนนี้นั่นเอง เพิ่มเติมผมไม่ได้เอาสไลด์ด้านบนมาอธิบายหมดนะครับ ลองไปอ่านทำความเข้าใจในสไลด์ตั่งแต่หน้าที่ 36 นะครับ

ผมไม่ได้บอกว่าอ่านบทความนี้จบแล้วจะไปเปลี่ยนโปรแกรมให้เป็น Flux นะ แค่ให้เห็นภาพ มองปัญหาให้ออกและวางโครงสร้างดีๆ ยังไงเราก็ต้องพึ่ง MVC ต่อไปนั่นละครับ

 

อ้างอิง

  • http://stackoverflow.com/questions/33447710/mvc-vs-flux-bidirectional-vs-unidirectional
  • https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture
  • https://facebook.github.io/flux/docs/overview.html#content
  • http://fluxxor.com/what-is-flux.html
  • http://www.pro-tekconsulting.com/blog/flux-vs-mvc/
  • http://www.christianalfoni.com/articles/2015_08_02_Why-we-are-doing-MVC-and-FLUX-wrong
  • speakerdeck.com/jviereck/from-mvc-to-flux
Facebook Comments