เรื่อง Business Logic ใน Model และ MVC
"ทำไมถึงมีคนบอกว่าเก็บ Business Logic ใน Model? ทั้งๆ ที่ MVC มัน concern กับ UI?"
ผมสรุปสั้นๆ แบบนี้ละกัน ว่า "Model" สำหรับบริบทนี้ มันไม่ได้เป็น Model ตัวเดียวกับ Model ใน MVC ซะทีเดียว
แต่เป็น "Model" ในลักษณะเดียวกับคำว่า Model ใน Mathematical Model, Business Model, Computation Model หรือว่า "ธรรมศาสตร์โมเดล" ตอนน้ำท่วม 54 อะไรแบบนี้
ขยายความยาวๆ ก็:
มันเป็นสิ่งที่ encapsulate สิ่งที่เราคิด หรือพูดอีกอย่างก็คือ model ของความคิดเราเองว่าคืออะไร ทำงานยังไง เปลี่ยนแปลงยังไง ฯลฯ
ในขณะที่ MVC ของ MVC Architecture Pattern มันไม่ได้สนใจตรงนั้น (คือ มันไม่ได้บอกว่า "ต้อง" อยู่ที่ไหน มันไม่มี concern เรื่องนี้เลย)
ซึ่ง Pattern แบบนี้ใช้เยอะในพวก Enterprise เพราะว่ามันมักจะมีระบบ ERP/Backend ที่ทำงานกับพวก Business Logic อะไรพวกนี้อยู่แล้ว แต่หน้าที่คนคือทำ UI ให้ทำงานกับข้อมูลนี้ในหน้าจอต่างๆ กัน
ทีนี้ มันมีประเด็นที่ทำให้คนสับสนอยู่ตรงนี้แหละ
คือ Framework หลายตัวในปัจจุบัน ที่ไม่ได้โตขึ้นมาจากทางฝั่ง Enterprise เค้าค่อนข้าง encourage ให้ใช้ "Model" (in general) สำหรับการทำ "Model" ใน MVC ไปเลย ยกตัวอย่างเช่น Ruby on Rails เป็นต้น
ซึ่งมันก็ make sense สำหรับงานที่ scale ยังไม่ใหญ่เท่าไหร่
ทีนี้เวลาที่งานมันเริ่มโตขึ้นมา เราเริ่มต้องการ "Representation ของ Data จาก Model เดียวกันในหลายแบบมากขึ้น" (เช่น JSON คนละแบบ) เราก็ควรจะ "งอก Layer ขึ้นมาใหม่ มาจัดการ concern ตรงนั้น"
ซึ่งตรงนี้จะเรียกอะไรก็เรียกไป หลายคนก็เรียกว่า VM (ViewModel) หลายคนก็เรียกว่า Presenter ... (สำหรับคนที่ใช้ Model in general ใน MVC) ... หลายคนก็เรียกว่า Model (สำหรับคนที่ Model คือ Model ใน MVC ตั้งแต่ต้น)
แต่ในขณะที่ Framework หลายตัว encourage แบบนี้ .... Framework อีกหลายตัว โดยเฉพาะที่โตมาจากฝั่ง Enterprise นี่คิดตรงข้ามเลย คือให้ Model เป็น Model จ๋าๆ ใน Presentation Tier ของ 3-tier อะไรแบบนี้ .... เอาไปใช้ใน UI Domain อย่างเดียวเลย
มันก็เลยสับสนกันง่าย
สำหรับหลายคน (หลาย community/culture/framework) แล้ว MVC มันคือ 3-Tier ตรงๆ เลย แต่สำหรับอีกหลายๆ คน (หลาย community/culture/framework) แล้วมัน concern อยู่แค่ใน Presentation tier
ผมเป็นคนหนึ่งที่บอกว่า Business Logic ควรอยู่ใน Model .... แต่ Model ของผมมันไม่ได้หมายถึง Model ใน MVC .... แค่ในบางกรณีมันเอาไปใช้ได้ตรงๆ
แต่นั่นมันหมายถึงว่า Business Logic ผมจะไม่กระจัดกระจายอยู่ใน Controller บ้าง Model บ้าง DB บ้าง View บ้าง ... มันจะไปกองที่เดียวคือ Model Layer
และ Model Layer ของผม มันไม่ได้มีแต่ "Data Model" แต่มันมีอะไรเยอะแยะอยู่ (คือมันมี Sublayer อยู่เยอะแหละ ก็งอกมาตามบริบาท เช่น ผมอาจจะมี BookPersist, BookEntity, BookUseCase, BookDataRule เฉพาะของ "Book" ก็ได้ ....)
พูดง่ายๆ แต่ว่าละไฟล์มันก็ไม่ได้เกิน 300 บรรทัดหรอก และเราก็แยก concern ในแต่ละเรื่องใน Model Layer อีกทีอยู่แล้ว :P
TLDR:
ถ้าถามว่า "Business Logic *ต้อง* อยู่ไหนใน MVC" คำตอบคือ "มันไม่มี concern เรื่องนี้ ไปคิดเอาเองว่าจะเอาไว้ไหน"
แต่ถ้าถามว่า "คนที่บอกว่า 'เก็บใน Model' นี่คิดอะไรอยู่" คำตอบก็จะเป็นประมาณนี้ ว่า Model ใน conceptual ของเขา มันคือ Object Model ที่มันใหญ่กว่า Model ใน MVC และมันรวม Model ใน MVC ไว้แล้ว น่ะแหละ ....
ซึ่งบังเอิญพอคิดแบบนี้แล้ว มันก็เลยกลายเป็นว่า "ไหนๆ ก็ต้องคิดเองเรื่อง Business Logic อยู่ไหนใน MVC แล้ว .... ก็ใน Model ไง มันก็ควรอยู่ตรงนั้นอยู่แล้ว"
และ "Model" ตรงนี้ หมายถึง Group ของ Objects/Classes ใน Model Layer ซึ่งอาจจะเต็มไปด้วย Design Pattern และ Architecture Pattern ... ไม่ได้หมายถึง Single Class ที่ยัดทุกอย่างไปรวมกันหมด
TLDR of TLDR:
Business Logic เก็บไว้ใน Model ครับ แต่มันคือ Model in General
ส่วนคุณจะใช้ Model ตัวนี้ใน MVC แบบไหน/ขนาดไหน ... มันเรื่องของคุณ ... เพราะตัว M ใน MVC มันไม่แคร์เรื่องนี้
อีกรอบ: สำหรับหลายคน (หลาย community/culture/framework) แล้ว MVC มันคือ 3-Tier ตรงๆ เลย แต่สำหรับอีกหลายๆ คน (หลาย community/culture/framework) แล้วมัน concern อยู่แค่ใน Presentation tier