วัน: 1 มกราคม 2020

Clean Architecture: Over-engineering & Boilerplate CodeClean Architecture: Over-engineering & Boilerplate Code

Clean Architecture (CA) เป็นแนวคิดที่ทรงพลังในการออกแบบซอฟต์แวร์ โดยเน้นการแยกส่วนประกอบ (Separation of Concerns) อย่างชัดเจน เพื่อให้ระบบมีความยืดหยุ่นและง่ายต่อการบำรุงรักษา อย่างไรก็ตาม ในทางปฏิบัติ การยึดติดกับหลักการนี้มากเกินไปอาจนำไปสู่ปัญหาที่เรียกว่า Over-engineering และการเพิ่ม Boilerplate Code จำนวนมหาศาล

สำหรับนักพัฒนาระบบที่ใช้ PostgreSQL เป็นแกนหลัก การทำความเข้าใจว่าเมื่อใดที่ควรใช้ความซับซ้อนของ CA และเมื่อใดที่ควรใช้ความสามารถในการจัดการข้อมูลระดับสูงของ PostgreSQL จะช่วยให้เราสร้างระบบที่สมดุลและมีประสิทธิภาพ บทความนี้จะเจาะลึกถึงกับดักเหล่านี้และเสนอแนวทางปฏิบัติที่ดีที่สุดโดยใช้ไวยากรณ์ของ PostgreSQL โดยเฉพาะ

The Trap: When Architecture Becomes the Problem

ปัญหาหลักของการ Over-engineering คือการเพิ่มชั้น (Layers) ของโค้ดที่ไม่มีมูลค่าเพิ่ม (Non-value-adding layers) เช่น การสร้าง Data Transfer Objects (DTOs) หรือ Repository Interfaces ที่ซับซ้อนเกินความจำเป็นสำหรับ Use Case ที่เรียบง่าย การทำเช่นนี้ทำให้โค้ดดูสะอาดทางทฤษฎี แต่กลับทำให้โค้ดจริง (Implementation) มีความยุ่งยากและกินเวลาในการพัฒนาโดยไม่จำเป็น

ในบริบทของ PostgreSQL เรามีเครื่องมือที่ทรงพลังมากในการจัดการโครงสร้างข้อมูลที่ซับซ้อนโดยตรงที่ชั้นฐานข้อมูล (Database Layer) ซึ่งสามารถช่วยลดความจำเป็นในการสร้างโค้ด Boilerplate ในชั้น Use Case ได้

Leveraging PostgreSQL for Simplicity

แทนที่จะให้ชั้น Application Service ทำหน้าที่แปลงข้อมูลจาก Entity ไปเป็น DTOs หลายชั้น เราสามารถใช้ความสามารถของ PostgreSQL เช่น JSONB, Common Table Expressions (CTEs), หรือฟังก์ชัน RETURNING เพื่อให้ฐานข้อมูลจัดการการรวมข้อมูล (Data Aggregation) และการจัดโครงสร้างข้อมูลที่ซับซ้อนให้เสร็จสิ้นตั้งแต่ต้นทาง

ตัวอย่างเช่น หากเราต้องการดึงข้อมูลผู้ใช้พร้อมรายการสินค้าที่เกี่ยวข้อง เราไม่จำเป็นต้องเขียนโค้ด Join และ Loop ในภาษาโปรแกรมภายนอก แต่สามารถให้ PostgreSQL จัดการการรวมข้อมูลเป็นโครงสร้าง JSON ที่พร้อมใช้งานได้ทันที:

SQL

-- Example: Retrieving user data and related items in a single JSON structure. -- This minimizes external boilerplate code. SELECT user_id, user_name, jsonb_agg(jsonb_build_object('item_id', item.id, 'name', item.name)) FROM users u JOIN items i ON u.id = i.user_id GROUP BY user_id, user_name HAVING COUNT(i.id) > 0;

การใช้คำสั่งนี้ช่วยให้เราลดความซับซ้อนของโค้ดในชั้น Use Case ได้อย่างมาก เพราะข้อมูลที่ออกมามีโครงสร้างที่พร้อมใช้งานเกือบ 100%

Conclusion: Finding the Sweet Spot

หัวใจสำคัญของการออกแบบระบบที่ประสบความสำเร็จไม่ใช่การปฏิบัติตามหลักการทางสถาปัตยกรรมอย่างเคร่งครัด แต่คือการเลือกใช้เครื่องมือที่เหมาะสมกับปัญหา (Right tool for the job) ในกรณีที่ใช้ PostgreSQL เป็นระบบหลัก เราควรพิจารณาให้ฐานข้อมูลรับผิดชอบการจัดการโครงสร้างข้อมูลที่ซับซ้อน (Data Structure Management) และให้โค้ดแอปพลิเคชันรับผิดชอบเพียง Business Logic ที่แท้จริงเท่านั้น

จงจำไว้ว่า: ความเรียบง่าย (Simplicity) ที่ถูกขับเคลื่อนด้วยพลังของฐานข้อมูล (PostgreSQL) มีค่ามากกว่าความซับซ้อนทางสถาปัตยกรรมที่เกินความจำเป็นเสมอ