Golang ในแบบของ MVC OOP

Prach CM
3 min readNov 21, 2020

--

picture credit : https://mrcook.uk/golang-vs-java-performance

เนื่องด้วยเรื่องของเรื่องเลย ผมทำงานสาย java มาก่อน เลยมักจะติดใจการเขียนแบบมี class มี interface ทีนี้พอมาลองใช้ golang อ้าวไม่มี 😂 ไม่พอโปรเจคเชิงโครงสร้าง mvc ที่ใช้หลักการ interface ก็หาได้ยากเย็นเหลือเกิน วันนี้เลยจะเอา demo project ที่ผมทำไว้มาแก้ใหม่ให้ทันเหตุการณ์ 😡 แล้วมาคุยกัน !!

สำหรับใครที่เคยดูบทความที่แล้ว ก็คือหลักการเดียวกันเลยครับ แต่บทความนี้ จะมาอธิบายในส่วนของการวางโครง mvc ซะมากกว่า โดยจะเขียนบน gin framwork นะครับ ซึ่งในนี้จะมีการใช้ gin context, bindjson ซึ่งเป็นสิ่งที่มาพร้อม framework ใครที่ใหม่กับ gin ลองไปตำลิ้งนี้ดู

วางโครงสร้างโปรเจคเริ่มต้น

$ mkdir go-soldier-mvc // create new project
$ go mod init github.com/krittawatcode/go-soldier-mvc
$ go get -u github.com/gin-gonic/gin
go-soldier-mvc project structure

ถัดมาครับ เราจะมาวางโครง controller กันก่อนครับ

จะเห็นว่า ที่วางไว้จะมี interface ขึ้นมาตัวนึงคือ SoldierController ซึ่งจะเป็นตัวที่ทุกคนเข้ามาอ่าน code เราก็จะรู้ได้ทันทีครับว่า อ๋อมี method อะไรบ้าง ถัดมาก็จะเป็นการเขียน soldierController ที่เป็น type struct ซึ่งในตรงนี้ จะต่างกับ java ที่เราเขียน class มา implement interface แต่ golang ไม่มี class มีแต่ struct เป็นตัวจัดโครงสร้างข้อมูล ดังนั้นสิ่งที่เราจะทำคือการ satisfy interface หรือก็คือ struct นั้นๆ จะต้องมี method ที่ สอดคล้องกับ interface นั้นๆ

A method on the other hand is declared by additionally specifying the “receiver” (which in OOP terms would be the “class” that the method is a part of)

ใครสนใจเรื่อง method vs func ก็ลองไปอ่านต่อในนี้ได้ครับ

อย่างในของเราก็คือเขียน method Eat() ที่มี receiver เป็น pointer ของ soldierController struct (ตัว pointer receiver จะเป็นตัวบอกว่า method นั้นๆจะใช้ได้แค่กับ struct ของ pointer เท่านั้น)

และที่ขาดไม่ได้ในการเขียน JAVA OOP สไตล์ก็คือ Constructer!!
แต่!!! golang เราไม่มี ดังนั้น เราจึงทำ func ตัวนึง ไว้สำหรับทำงาน setter ค่าให้กับ struct ของเรา ก็คือ soldierHandler

สิ่งที่ขาดไม่ได้เลย อยากให้สังเกตุใน struct สิ่งที่เราสร้างให้ ก็คือ มี dutyService เป็น field ของ struct ซึ่งตรงนี้หละ จะทำให้คนเรามาอ่าน code เราเข้าใจได้ว่า controller นี้ มี method อะไรบ้าง และจะไปเรียก service ตัวไหน

ต่อมาก็เขียน service กัน

service ที่เขียนมาก็จะมีโครงสร้างแบบเดิมเลย คือ มี interface -> struct -> method ที่ satisfy interface

ซึ่งใน service นี้ก็จะมีการนำข้อมูลจากภายนอกมาใช้ ดังนั้นเราจึงสร้าง model ขึ้นมาเพื่อรับค่าตรงนั้น และรอนำไปใช้ต่ออีกที (ปล. ในที่นี้อาจจะเห็นความซ้ำซ้อน ของ struct soldierInfo และ struct model soldier_model นิดหน่อย)

หลักจากของครบ ก็ไปเขียน main กัน

จะเห็นว่า ในการเรียกใช้ API เส้น /eat นั้น จะมีการทำงานหลักๆสามงาน

หนึ่งคือ เรียก service.SoldierDutyService() เพื่อทำการ set ค่าให้ service อนึ่งเหมือน set ค่าผ่าน contructer
สองคือ เรียก controller.SoldierHandler(&dutyService)
และเมื่อปั้น object เสร็จแล้ว ก็ทำ soldierController.Eat(c)

เสร็จหมดทุกอย่างแล้ว อย่างนั้นก็รัน service กัน!!

$ go run main.go

หลักจากนั้นก็ลอง POST ใน postman กัน

ก็จะเห็นว่าเมื่อยิง postman ด้วย rank “Corporal” สิบโท ก็จะได้ว่าเงินเดือนลดลง

อะลองยิงใหม่

อะ ก็จะเห็นว่าเมื่อใส่ corruption เป็น true และ rank เป็น General ก็จะได้ wife salary home car เพิ่มขึ้นมาทันที 😂😂😂

ปล. ทั้งหมดทั้งมวลนี่ทำเพื่อบรรทัดสุดท้ายนี้เลย 555 ใครถูกใจก็อย่าลืมปรบมือให้กำลังใจ กด follow กันไว้อุ่นใจดี

โอเคครับ ก็คงจบแล้ว สำหรับ demo เบื้องต้น หวังว่าจะถูกใจทุกคนนะ สำหรับใครที่เพิ่งเขียนแล้วอยากวางโครงสวยๆ code อ่านง่าย การเขียน mvc แบบมี interface ก็ช่วยทำให้ code เราอ่านง่ายขึ้น และเป็นโครงสร้างมากขึ้น!

หากใครอยากได้ demo ก็ไปตำกันได้เลย

--

--

Prach CM
Prach CM

Written by Prach CM

Gopher <3 and Blockchain Dev

No responses yet