ในโลกของการพัฒนาระบบซอฟต์แวร์ที่ซับซ้อน การออกแบบสถาปัตยกรรม (Architecture) ที่แข็งแกร่งถือเป็นหัวใจสำคัญ Clean Architecture ไม่ใช่แค่ชื่อเทคนิค แต่เป็นชุดของหลักการที่ช่วยให้โค้ดของเรามีความยืดหยุ่น (Flexible) และสามารถบำรุงรักษาได้ง่าย (Maintainable) โดยเฉพาะอย่างยิ่งเมื่อเราใช้ระบบฐานข้อมูลที่มีประสิทธิภาพสูงอย่าง PostgreSQL
💡 Clean Architecture คืออะไร? ที่มาและเป้าหมาย
Clean Architecture ถูกเสนอขึ้นมาเพื่อแก้ไขปัญหาที่ระบบซอฟต์แวร์มักจะเกิดภาวะที่ส่วนประกอบต่างๆ ผูกติดกันมากเกินไป (Tight Coupling) จนเมื่อต้องการเปลี่ยนเทคโนโลยีใดเทคโนโลยีหนึ่ง (เช่น เปลี่ยนจาก PostgreSQL เป็น MongoDB หรือเปลี่ยน ORM) จะส่งผลกระทบต่อโค้ดส่วนอื่นทั้งหมด
🎯 เป้าหมายหลัก: การแยกความรับผิดชอบ (Separation of Concerns)
เป้าหมายหลักของ Clean Architecture คือการแยกส่วนประกอบทางธุรกิจ (Business Logic หรือ Domain) ออกจากรายละเอียดทางเทคนิค (Technical Details) อย่างเด็ดขาด องค์ประกอบทางธุรกิจจะต้องไม่รู้ว่าข้อมูลกำลังถูกจัดเก็บในฐานข้อมูลใด หรือใช้เฟรมเวิร์กใดในการติดต่อสื่อสาร
ในบริบทของ PostgreSQL เราจะใช้หลักการนี้เพื่อสร้างชั้น (Layers) ที่ชัดเจน:
- Domain Layer (Use Cases): เป็นหัวใจของระบบ มีแต่กฎทางธุรกิจ ไม่ยุ่งเกี่ยวกับ SQL เลย
- Interface/Port Layer (Repositories): กำหนดสัญญา (Contract) ว่าต้องทำอะไรได้บ้าง เช่น ต้องมีฟังก์ชัน `get_user_by_id(id)`
- Database Layer (PostgreSQL): เป็นส่วนที่ทำหน้าที่รัน SQL จริงๆ เพื่อตอบสนองสัญญาที่กำหนดไว้
🛠️ การประยุกต์ใช้ Clean Architecture กับ PostgreSQL
เมื่อเราออกแบบระบบโดยใช้ PostgreSQL เราต้องมั่นใจว่าชั้น Use Case ของเราเรียกใช้ Repository Interface เท่านั้น ไม่ใช่การเรียกใช้คำสั่ง SQL โดยตรง การทำเช่นนี้ทำให้เราสามารถจำลอง (Mock) ฐานข้อมูลเพื่อทดสอบ Business Logic ได้อย่างสมบูรณ์ โดยไม่ต้องเชื่อมต่อกับฐานข้อมูลจริงเลย
ตัวอย่างการแยกชั้นใน PostgreSQL:
สมมติว่าเราต้องการดึงรายละเอียดสินค้า 3 รายการ (1, 2, 3) โดยใช้ PostgreSQL เราจะสร้างฟังก์ชันที่จำลอง Use Case ซึ่งรับผิดชอบการเรียกข้อมูลเท่านั้น:
SQL
-- 1. สร้างตารางข้อมูล (Database Layer) --------------------------------
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100)
);
-- 2. แทรกข้อมูลตัวอย่าง (Short Strings)
INSERT INTO products (id, name) VALUES (1, 'apple'), (2, 'banana'), (3, 'orange');
-- 3. สร้าง Use Case Function (จำลองการเรียกใช้ข้อมูล) ----------------------
CREATE OR REPLACE FUNCTION get_product_details(p_ids text)
RETURNS TABLE (id INT, name VARCHAR)
AS $$
BEGIN
-- Logic นี้คือการตอบสนองสัญญา (Repository Implementation)
RETURN QUERY SELECT p.id, p.name FROM products p WHERE p.id = ANY(string_to_array(p_ids, ',')::INT[]);
END;
$$ LANGUAGE plpgsql;
-- 4. การเรียกใช้ (Use Case Execution)
SELECT * FROM get_product_details('1,2,3');
ในโค้ดนี้ ฟังก์ชัน `get_product_details` ทำหน้าที่เป็นตัวเชื่อมที่รับผิดชอบการรวบรวมข้อมูล (Use Case) โดยที่ชั้น Use Case ไม่จำเป็นต้องรู้ว่าข้อมูลมาจากตาราง `products` หรือใช้ภาษา SQL ใด เพียงแค่รู้ว่าต้องส่งรายการ ID เข้าไปเท่านั้น
✅ บทสรุป: ประโยชน์ที่ได้รับ
การยึดตามหลัก Clean Architecture เมื่อทำงานกับ PostgreSQL จะช่วยให้เราได้ระบบที่มีความยืดหยุ่นสูง (Decoupled) หากในอนาคตเราต้องการเปลี่ยนจาก PostgreSQL ไปใช้ฐานข้อมูลอื่น เราเพียงแค่เขียน Repository ใหม่ให้สอดคล้องกับสัญญาเดิม โดยที่ Business Logic หลักของเราไม่จำเป็นต้องถูกแก้ไขเลย นี่คือการลงทุนด้านสถาปัตยกรรมที่คุ้มค่าที่สุดสำหรับโปรเจกต์ขนาดใหญ่