เพิ่มเติมกับ Clean Architecture
รู้จัก Clean Architecture เพิ่มเติม
Ref: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
แน่นอน Hexagonal Architecture ไม่ใช่รูปแบบเดียวที่สามารถใช้สำหรับการวาง code ของภาษา Go
อีกรูปแบบหนึ่งที่ถือว่า ใกล้เคียงกับ Hexagonal Architecture และเป็นที่นิยมเช่นเดียวกันนั่นก็คือ Clean Architecture
Clean Architecture คือหลักการที่พัฒนาโดย Robert C. Martin's เป็น architecture ที่พยายามแยกส่วนของ application ออกจากกันเพื่อไม่ให้มี Dependency ต่อกัน (pain point เหมือนๆกันกับ Hexagonal Architecture) เพื่อให้ code สามารถเข้าใจได้ง่ายขึ้น maintain ได้ง่ายขึ้น และสามารถ test ได้ง่ายขึ้น
โดย Clean Architecture นั้นมีการแบ่งองค์ประกอบใหญ่ๆออกเป็น 4 ชั้น (เหมือนวงกลม 4 วงที่ซ้อนกันตามภาพด้านบน) โดยพยายามมองจากส่วนที่ลึกที่สุด (ส่วนที่เป็นการจัดการข้อมูลสำคัญ) ไปจนถึงส่วนข้างนอกที่สุด (ส่วนที่มีการพูดค ุยกับ user) คือ Entities, Use Cases, Interface Adapters และ Frameworks & Drivers โดยทั้ง 4 ชั้นมีหน้าที่ดังนี้
- Entities คือการกำกับสิ่งที่เรียกว่า "business object" เอาไว้ โดยมีหน้าที่ใหญ่ๆในการกำหนด "โครงสร้างข้อมูล" โดยจะเป็นการกำหนดกฎของภาพใหญ่ไว้ว่า application นี้ต้องทำอะไรได้บ้างและมีข้อมูลที่เก็บลักษณะไหนบ้าง
- ซึ่งจริงๆใน Layer นี้จะรวมถึงการจัดการกับ Database ด้วย หลายๆแหล่งจะเรียกว่า Repository
- ดังนั้น Entities จึงเป็นการพูดถึงโครงสร้างข้อมูลและการจัดการข้อมูลนั่นเอง
-
Use Cases ประกอบด้วย application specific business rule ที่ทำการประกอบ business logic เอาไว้ เป็นเหมือน use case การใช้งานของระบบว่าระบบสามารถใช้งานอะไรได้บ้าง
-
Interface Adapters เป็นส่วนสำหรับการแปลงข้อมูลจาก format ที่รับเข้ามา ให้เป็น format ที่สามารถนำไปใช้ใน use case และ entities ต่อได้
- เป็นส่วนที่เหมือนสะพานระหว่าง ส่วนที่อยู่ภายใน (Entities, Use cases) กับ ภายนอก (Framework & Driver หรือ external interface อย่าง database, Web API)
- layer นี้เป็นส่วนที่รับต่อมาและทำการจัดการข้อมูลให้ถูกต้องก่อนจะนำไปใช้งานต่อ (คล้ายๆกับ Adapter ของ Hexagonal Architecture)
- Frameworks and Drivers. เป็นส่วนที่อยู่นอกสุดซึ่งก็คือส่วนที่มีการเชื่อมต่อกับฝั่งผู้ใช้ และ service ภายนอกเช่น Database, Web framework
- ใน layer นี้จะมีเพียงการเรียกใช้อย่างเดียว จะมี code ไม่เยอะมาก เปรียบเสมือนการประสานทุกส่วนเข้าด้วยกันเพื่อให้สามารถคุยกันภายในวงกลมทั่วทั้งวงได้ (ส่งข้อมูลต่อไปหากันได้)
มาลองดูตัวอย่างการวาง Clean Architecture กัน
ถ้าเราลองวาดเป็น Diagram ดู ด้วยโจทย์เด ียวกันกับ Hexagonal จะได้ Diagram ประมาณนี้ออกมาแทน
เดี๋ยวเราจะมาไล่อธิบายผ่าน code กัน แต่จาก Diagram นี้ เราจะเทียบหน้าที่ออกเป็น
- Entities คือส่วนของ
Order Entity
ที่เป็นการประกาศโครงสร้างของข้อมูล Order เอาไว้ ว่าข้อมูล Order มีลักษณะเป็นอย่างไร - Use case คือส่วนของการใช้งาน ซึ่งในที่นี่คือ function
createOrder
สำหรับการสร้าง Order ซึ่งจะเก็บเอาไว้ในOrder Service
- โดย
Order Service
นั้นก็จะอ้างอิงโครงสร้างของ Order ตามOrder Entity
ที่อยู่ใน layer ด้านในสุดอีกที
- Interface Adapters คือส่วนของการแปลงข้อมูลเพื่อทำการส่งไปยัง Use case เพื่อให้ Use case สามารถจัดการต่อได้ถูกได้จะมีทั้งหมด 2 ส่วนคือ
GORM Order Repository
คือส่วนที่จะทำการสร้าง function สำหรับจัดการ database และคำสั่งเกี่ยวกับการquery database
(เพื่อทำการส่งคำสั่งquery
นี้ไปยังOrder Service
เพื่อให้Order Service
สามารถนำคำสั่งนี้ไปสร้าง Order ต่อได้ภายใน logic ของ use case ตัวเอง)HTTP Order Handler
คือส่วนที่จะทำการสร้าง function สำหรับจัดการ data ที่ผ่านเข้ามาทาง HTTP Request ทำการแปลงให้ถูกต้องเพื่อทำการส่งข้อมูลให้Order Service
ให้เป็นไปตาม structure ของOrder
ได้ถูกต้อง (ทำหน้าที่เหมือนตัวแปลงข้อมูลจากภายนอกให้ตรงตาม use case)
- Frameworks and Drivers Layer คือส่วนของการเชื่อมต่อกับ Application ภายนอกโดย
Fiber HTTP Server
คือ HTTP Server ที่ทำการสร้าง API เพื่อรับ request จากฝั่ง user เข้ามา เพื่อส่งต่อไปยัง Interface ของ HTTPGORM Database Interface
คือส่วนของ Config database ที่ทำการเชื่อมกับ database เพื่อส่งต่อไปยัง Interface ของ Gorm
และท้ายที่สุดเมื่อเอาทั้ง 4 ส่วนมาประกอบกัน (ผ่าน main.go
คล้ายๆกับ Hexagonal Architecture) ก็จะสามารถสร้าง application 1 ตัวที่ทำการ run ทุกส่วนแยกกันออกมาได้
เดี๋ยวเรามาลองดู code จริงเพื่อเทียบกันว่า ทั้ง 2 วิธีมีวิธีก าร implement code แตกต่างกันอย่างไรบ้าง