PlusMagi's Blog By Pitt Phunsanit Backend,Database Dependency Injection & Navigation (การจัดการ Lifecycle, DI Container และ Routing/Page Navigation)

Dependency Injection & Navigation (การจัดการ Lifecycle, DI Container และ Routing/Page Navigation)

ในโลกของระบบฐานข้อมูลขนาดใหญ่ (Enterprise Database) การออกแบบที่แข็งแกร่งไม่ได้หมายถึงแค่การเขียน Query ที่ซับซ้อนเท่านั้น แต่คือการสร้างสถาปัตยกรรมที่สามารถจัดการการพึ่งพา (Dependency) และวงจรชีวิต (Lifecycle) ของข้อมูลและกระบวนการได้อย่างเป็นระเบียบ เมื่อระบบขยายตัว การควบคุมความสัมพันธ์ระหว่างส่วนประกอบย่อยจึงเป็นหัวใจสำคัญที่นักพัฒนาต้องให้ความสนใจ

บทความนี้จะเจาะลึกแนวคิด Dependency Injection (DI) และการจัดการวงจรชีวิต (Lifecycle Management) โดยนำหลักการเหล่านี้มาประยุกต์ใช้กับ PostgreSQL เพื่อให้มั่นใจว่าโค้ด (Stored Procedures/Functions) ของเรามีความยืดหยุ่นสูง ทดสอบง่าย และป้องกันปัญหา State Leakage ได้อย่างสมบูรณ์

💡 Dependency Injection (DI) ในบริบทของ PostgreSQL

โดยทั่วไป DI คือการที่ส่วนประกอบไม่สร้าง Dependencies ของตัวเอง แต่รับมันมาจากภายนอก (Inversion of Control – IoC) ใน PostgreSQL เราสามารถจำลองหลักการนี้ได้โดยการออกแบบฟังก์ชัน (Functions) ให้รับพารามิเตอร์ที่จำเป็นทั้งหมดแทนการให้ฟังก์ชันนั้นไปเรียกใช้โมดูลหรือตารางอื่นโดยตรง ทำให้ฟังก์ชันนั้นเป็นแบบ ‘Pure Function’ ที่พึ่งพาเฉพาะ Input ที่ได้รับเท่านั้น

การออกแบบเช่นนี้ช่วยลดการ Coupling ระหว่างโมดูล ทำให้เราสามารถทดสอบฟังก์ชันย่อยแต่ละตัวได้อย่างอิสระ (Unit Testing) โดยไม่ต้องตั้งค่าสภาพแวดล้อมที่ซับซ้อน

🔄 Lifecycle Management และ Routing ด้วย Transactions

การจัดการวงจรชีวิตของข้อมูล (Data Lifecycle) คือการควบคุมว่าข้อมูลจะถูกสร้าง (Create), อ่าน (Read), อัปเดต (Update), และลบ (Delete) อย่างไร โดยเฉพาะอย่างยิ่งในกระบวนการที่ซับซ้อน เราต้องมั่นใจว่าทุกขั้นตอนจะสำเร็จทั้งหมด หรือหากมีขั้นตอนใดล้มเหลว ระบบจะต้องย้อนกลับสู่สถานะเดิม (Rollback) ซึ่งคือการจัดการ Transaction Boundary

ในส่วนของ ‘Routing’ หรือการนำทางในบริบทของ DB คือการออกแบบฟังก์ชันหลัก (Orchestrator Function) ที่ทำหน้าที่เรียกใช้ฟังก์ชันย่อย ๆ (Micro-services/Modules) ตามลำดับที่ถูกต้อง และจัดการการส่งผ่านข้อมูล (Dependencies) ระหว่างฟังก์ชันเหล่านั้น

ตัวอย่างการจำลอง Lifecycle และ Dependency

สมมติว่าเรามีกระบวนการสั่งซื้อสินค้าที่ต้องผ่าน 3 ขั้นตอน: 1) ตรวจสอบสินค้า, 2) บันทึกการสั่งซื้อ, และ 3) อัปเดตสต็อก ฟังก์ชันหลักจะต้องควบคุมวงจรชีวิตนี้ทั้งหมด:

SQL

-- 1. สร้างฟังก์ชันย่อย (Dependencies) ที่เป็นอิสระ<br>CREATE OR REPLACE FUNCTION check_inventory(product_id INT, quantity INT) RETURNS BOOLEAN AS $$<br>BEGIN<br>    -- จำลองการตรวจสอบสินค้า<br>    RETURN TRUE;<br>END;$$ LANGUAGE plpgsql;<br><br>-- 2. ฟังก์ชันหลัก (Router/Orchestrator) ที่ควบคุม Lifecycle<br>CREATE OR REPLACE FUNCTION process_order(order_id INT, product_id INT, quantity INT) RETURNS BOOLEAN AS $$<br>DECLARE<br>    inventory_ok BOOLEAN;<br>BEGIN<br>    -- BEGIN Transaction Boundary (Start Lifecycle)<br>    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;<br>    <br>    -- Step 1: Check Dependency (Call sub-function)<br>    inventory_ok := check_inventory(product_id, quantity);<br>    IF NOT inventory_ok THEN<br>        RAISE EXCEPTION 'Inventory check failed.';<br>    END IF;<br>    <br>    -- Step 2: Core Logic (Update Order/Stock)<br>    -- INSERT INTO orders (order_id, product_id) VALUES (order_id, product_id);<br>    -- UPDATE inventory SET stock = stock - quantity WHERE product_id = product_id;<br>    <br>    -- COMMIT (Successful Lifecycle End)<br>    RETURN TRUE;<br>EXCEPTION<br>    -- ROLLBACK (Failed Lifecycle End)<br>WHEN OTHERS THEN<br>    RAISE NOTICE 'Transaction failed and rolled back.';<br>    RETURN FALSE;<br>END;$$ LANGUAGE plpgsql;<br><br>-- การเรียกใช้งาน (Simulated Call)<br>SELECT process_order(1001, 1, 2);<br>

✅ บทสรุป: การออกแบบที่ยืดหยุ่น

การใช้หลักการ DI และ Lifecycle Management ใน PostgreSQL ไม่ได้หมายถึงการใช้ Framework ภายนอก แต่คือการออกแบบสถาปัตยกรรมฐานข้อมูลให้มีขอบเขตความรับผิดชอบ (Single Responsibility) ที่ชัดเจน การใช้ Transaction Boundaries และการแยกฟังก์ชันย่อย ๆ ออกมาเป็นโมดูลที่รับ Dependencies ผ่าน Parameters จะช่วยให้ระบบของเรามีความทนทาน (Resilience) สามารถทดสอบได้ง่าย และรองรับการขยายตัวของฟีเจอร์ใหม่ ๆ ได้อย่างมีประสิทธิภาพสูงสุด