PlusMagi's Blog By Pitt Phunsanit Database Tabulator Wrapper Class: การสร้างคลาสกลาง (TabulatorPlus) เพื่อใช้งานร่วมกับ Framework ต่าง ๆ

Tabulator Wrapper Class: การสร้างคลาสกลาง (TabulatorPlus) เพื่อใช้งานร่วมกับ Framework ต่าง ๆ

ในฐานะ System Specialist และ Senior Architect เราทราบดีว่าการพัฒนาแอปพลิเคชันขนาดใหญ่ (Enterprise Applications) มักเผชิญกับความท้าทายในการจัดการกับการพึ่งพาโครงสร้างข้อมูลที่ซับซ้อน การเรียกใช้ SQL ที่มี Join หรือ Logic ซับซ้อนโดยตรงจาก Service Layer ทำให้โค้ดของเราเกิดภาวะ ‘Tight Coupling’ กับรายละเอียดของ Schema ซึ่งส่งผลให้การบำรุงรักษา (Maintainability) และความสามารถในการขยายตัว (Scalability) ลดลงอย่างมาก

แนวคิดของการสร้าง Wrapper Class หรือที่ในโลกฐานข้อมูลเราเรียกว่า Abstraction Layer คือการสร้างชั้นนามธรรมขึ้นมาเพื่อทำหน้าที่เป็นตัวกลางระหว่าง Business Logic ของแอปพลิเคชันกับโครงสร้างของตารางและ Query ที่ซับซ้อนภายใน PostgreSQL โดยแทนที่จะให้ Service Layer ต้องเขียน SQL ที่เต็มไปด้วย CTEs, Joins, และ Type Casting เอง เราจะห่อหุ้ม (Wrap) ตรรกะเหล่านั้นไว้ใน Stored Function หรือ View

หลักการทำงานของ Abstraction Layer ใน PostgreSQL

Wrapper Layer นี้ทำหน้าที่เป็น ‘API’ ของฐานข้อมูลเอง มันรับ Input ที่เข้าใจง่าย (เช่น ID, Status) และจัดการกับความซับซ้อนทั้งหมดที่อยู่เบื้องหลัง เช่น การ Join ข้อมูลจากตาราง 5 ตาราง หรือการคำนวณค่ารวมแบบ Recursive CTEs จากนั้นจึงส่งผลลัพธ์ออกมาในรูปแบบที่เป็นมาตรฐานและคาดเดาได้ (เช่น JSONB)

ตัวอย่าง: การห่อหุ้ม Logic ด้วย PostgreSQL Function

สมมติว่าเรามีตารางข้อมูลหลายส่วนที่ต้องนำมาคำนวณเพื่อแสดงผลลัพธ์เดียว (เช่น ข้อมูล Order, User, และ Payment History) แทนที่จะให้ Service Layer เขียน Query ยาว ๆ เราจะสร้างฟังก์ชันที่ทำหน้าที่นี้:

SQL

-- 1. Setup: สร้างตารางจำลองและข้อมูลตัวอย่าง (Simplified Schema)
CREATE TABLE users (user_id INT PRIMARY KEY, username TEXT);
CREATE TABLE orders (order_id INT PRIMARY KEY, user_id INT REFERENCES users(user_id), order_date DATE);

-- 2. The Wrapper Function: ห่อหุ้ม Logic ที่ซับซ้อนทั้งหมด
CREATE OR REPLACE FUNCTION get_user_summary(p_user_id INT) RETURNS JSONB AS $$ 
BEGIN
    RETURN jsonb_build_object(
        'user_info', (SELECT jsonb_build_object('username', username) FROM users WHERE user_id = p_user_id),
        'total_orders', (SELECT COUNT(order_id) FROM orders WHERE user_id = p_user_id),
        'recent_activity', ( 
            SELECT jsonb_agg(jsonb_build_object('order_id', order_id, 'date', order_date)) 
            FROM orders 
            WHERE user_id = p_user_id ORDER BY order_date DESC LIMIT 5
        )
    );
END; 
$$ LANGUAGE plpgsql;

-- การเรียกใช้ (Service Layer จะเรียกแค่ฟังก์ชันนี้เท่านั้น)
SELECT get_user_summary(1);

ประโยชน์ทางสถาปัตยกรรมที่ได้รับ

  • Decoupling (การแยกส่วน): Service Layer ไม่ต้องรู้ว่าข้อมูลมาจากตารางไหนบ้าง มันแค่เรียก `get_user_summary(1)` เท่านั้น ทำให้เราสามารถเปลี่ยนโครงสร้างตารางภายในได้โดยไม่กระทบโค้ด Business Logic
  • Single Responsibility Principle: ฟังก์ชันนี้มีหน้าที่เดียวคือการรวบรวมและจัดรูปแบบข้อมูลสรุปของผู้ใช้ทั้งหมด ทำให้โค้ดมีความสะอาดและทดสอบง่าย (Testable)
  • Security & Consistency: การบังคับให้ทุกส่วนของแอปพลิเคชันต้องเรียกผ่าน Wrapper Function ช่วยป้องกันไม่ให้เกิด Query ที่ผิดพลาดหรือเปิดเผยรายละเอียด Schema โดยไม่ได้ตั้งใจ

สรุป

การใช้ Abstraction Layer ใน PostgreSQL ไม่ใช่แค่เรื่องของการเขียนโค้ดที่ดูดี แต่คือการยกระดับสถาปัตยกรรมฐานข้อมูลให้มีความทนทาน (Resilience) และความสามารถในการขยายตัวในระดับองค์กร มันช่วยให้ทีมพัฒนาโฟกัสกับ Business Logic ได้เต็มที่ โดยไม่ต้องมาเสียเวลาจัดการกับรายละเอียดปลีกย่อยของการ Join ตารางหรือการคำนวณที่ซับซ้อนอีกต่อไป นี่คือแนวทางปฏิบัติของ Senior Architect ที่แท้จริง

Exit mobile version