วัน: 5 กุมภาพันธ์ 2004

Architecture & Patterns (MVVM Pattern, Data Binding, Dependency Injection, ServiceCollection)Architecture & Patterns (MVVM Pattern, Data Binding, Dependency Injection, ServiceCollection)

ในฐานะสถาปนิกระบบระดับสูง การออกแบบฐานข้อมูลที่แข็งแกร่งไม่ได้หมายถึงแค่การสร้างตารางที่ถูกต้อง แต่หมายถึงการสร้างสถาปัตยกรรมที่สามารถรองรับการเปลี่ยนแปลงทางธุรกิจได้อย่างยืดหยุ่นและดูแลรักษาได้ (Maintainable) แม้ว่า MVVM, Data Binding, และ Dependency Injection จะเป็นแนวคิดที่มาจากชั้นแอปพลิเคชัน (Application Layer) แต่หลักการเหล่านี้ก็สามารถนำมาปรับใช้เพื่อยกระดับการออกแบบฐานข้อมูลเชิงสัมพันธ์ (Relational Database) อย่าง PostgreSQL ได้อย่างมีประสิทธิภาพ

การประยุกต์ใช้หลักการสถาปัตยกรรมใน PostgreSQL

หัวใจสำคัญของการออกแบบฐานข้อมูลสมัยใหม่คือ การแยกความรับผิดชอบ (Separation of Concerns) ซึ่งในบริบทของ PostgreSQL เราใช้ Stored Procedures และ Functions เข้ามาทำหน้าที่นี้แทน View ธรรมดา เพื่อให้ตรรกะทางธุรกิจ (Business Logic) ถูกเก็บไว้ในฐานข้อมูลอย่างเป็นระบบ

1. Separation of Concerns (แทน MVVM Pattern)

แทนที่จะให้โค้ดแอปพลิเคชันเรียกใช้คำสั่ง SELECT * FROM table โดยตรง ซึ่งทำให้ View และ Model ผสมปนเปกัน เราควรสร้างฟังก์ชันที่ทำหน้าที่เป็น ‘ViewModel’ ที่รับผิดชอบการคำนวณและส่งคืนข้อมูลที่พร้อมใช้งาน (View Model) เท่านั้น

2. Data Binding (ผ่าน Triggers และ Views)

Data Binding คือกลไกที่รับประกันว่าเมื่อข้อมูลต้นทาง (Source Data) เปลี่ยนแปลง ข้อมูลปลายทาง (Target Data) จะอัปเดตตามโดยอัตโนมัติ ใน PostgreSQL เราใช้ Triggers และ Views ที่ซับซ้อนเพื่อจำลองพฤติกรรมนี้ ตัวอย่างเช่น เมื่อมีการบันทึกคำสั่งซื้อ (Order) ระบบควรจะอัปเดตสต็อกสินค้า (Product Stock) ทันที

3. Dependency Injection (ผ่าน Function Parameters)

DI คือการที่ส่วนประกอบต่างๆ ไม่ต้องรู้ว่าต้องสร้าง Dependencies ของตัวเอง แต่จะได้รับมันมาภายนอก ใน PostgreSQL เราจำลองหลักการนี้โดยการออกแบบ Functions ให้รับพารามิเตอร์ (Parameters) ที่จำเป็นอย่างชัดเจน ทำให้ฟังก์ชันนั้นๆ มีความอิสระและสามารถนำไปใช้ซ้ำได้โดยไม่ขึ้นอยู่กับสถานะของข้อมูลอื่นที่ไม่เกี่ยวข้อง

ตัวอย่างการใช้งาน PostgreSQL (Product Inventory System)

เราจะใช้ฟังก์ชันเพื่อจัดการการลดสต็อกสินค้า ซึ่งเป็นการรวมหลักการ Separation of Concerns และ Data Binding เข้าด้วยกัน

SQL

-- 1. สร้างตารางสินค้า (Model) และตั้งค่าเริ่มต้น<br>CREATE TABLE products (id SERIAL PRIMARY KEY, name VARCHAR(100), stock INT NOT NULL);<br>INSERT INTO products (name, stock) VALUES ('apple', 100);<br>INSERT INTO products (name, stock) VALUES ('banana', 50);<br><br>-- 2. สร้าง Function (ViewModel/Logic Layer) เพื่อจัดการการลดสต็อก<br>CREATE OR REPLACE FUNCTION update_stock_level(p_product_id INT, p_quantity INT) RETURNS VOID AS $$<br>BEGIN<br>    -- ตรวจสอบว่าสต็อกเพียงพอหรือไม่<br>    IF (SELECT stock FROM products WHERE id = p_product_id) >= p_quantity THEN<br>        UPDATE products<br>        SET stock = stock - p_quantity<br>        WHERE id = p_product_id;<br>    ELSE<br>        RAISE EXCEPTION 'Insufficient stock for product ID %', p_product_id;<br>    END IF;<br>END;<br>$$ LANGUAGE plpgsql;<br><br>-- 3. การเรียกใช้ (Dependency Injection: ส่งค่าที่จำเป็นเข้าไป)<br>SELECT update_stock_level(1, 10); -- ลดสต็อก apple 10 หน่วย<br>SELECT update_stock_level(2, 5);  -- ลดสต็อก banana 5 หน่วย<br><br>-- ตรวจสอบผลลัพธ์<br>SELECT * FROM products;<br>

บทสรุปสำหรับสถาปนิกระบบ

การนำหลักการสถาปัตยกรรมเหล่านี้มาใช้ใน PostgreSQL ช่วยให้ฐานข้อมูลของเราไม่ได้เป็นเพียงแค่ที่เก็บข้อมูล แต่เป็น ‘หน่วยประมวลผล’ ที่มีความฉลาดและเป็นระเบียบ การใช้ Functions และ Triggers อย่างเหมาะสมจะช่วยลดความซับซ้อนของโค้ดแอปพลิเคชันภายนอก ทำให้ระบบโดยรวมมีความทนทาน (Resilient), ทดสอบได้ (Testable), และง่ายต่อการบำรุงรักษาในระยะยาว ซึ่งเป็นคุณสมบัติสำคัญของ Senior Architect ที่ดี