ป้ายกำกับ: ตั๋วแจ้งปัญหา

Clean Architecture: Ports and Adapters (Hexagonal Architecture)Clean Architecture: Ports and Adapters (Hexagonal Architecture)

ในฐานะ Senior Architect การออกแบบระบบที่ยืดหยุ่นและสามารถบำรุงรักษาได้สูงถือเป็นหัวใจสำคัญของงานวิศวกรรมซอฟต์แวร์ หนึ่งในแนวคิดที่ทรงพลังที่สุดคือ Clean Architecture หรือที่รู้จักกันในชื่อ Ports and Adapters (สถาปัตยกรรมแบบรังผึ้ง) แนวคิดนี้มีเป้าหมายหลักในการแยกส่วน (Decouple) โลจิกทางธุรกิจ (Business Logic) ออกจากรายละเอียดทางเทคนิคภายนอก เช่น ฐานข้อมูล, UI, หรือเฟรมเวิร์ก

Ports and Adapters คืออะไรในการใช้งานกับ PostgreSQL

Ports and Adapters เป็นการกำหนดขอบเขตที่ชัดเจน โดยที่ Port คืออินเทอร์เฟซ (Interface) ที่กำหนดว่าระบบต้องการทำอะไร (เช่น ‘ฉันต้องการบันทึกข้อมูลสินค้า’) ส่วน Adapter คือส่วนที่ทำหน้าที่นำ Port นั้นไปปฏิบัติจริงกับเทคโนโลยีภายนอก (เช่น การใช้คำสั่ง SQL ของ PostgreSQL เพื่อบันทึกข้อมูล)

เมื่อเราใช้ PostgreSQL เป็นฐานข้อมูล เราจะมองว่า PostgreSQL คือ Adapter ตัวหนึ่งที่ทำหน้าที่ตอบสนองต่อ Port ที่กำหนดไว้ในชั้น Business Logic โดยที่ Business Logic ไม่จำเป็นต้องรู้ว่าข้อมูลถูกเก็บด้วย PostgreSQL, MySQL, หรือแม้แต่ไฟล์ JSON

การจำลองการทำงานด้วย PostgreSQL Adapter

สมมติว่าเรามีระบบจัดการสินค้า (Product Management) Port ของเราคือการบันทึกรายการสินค้าใหม่ ซึ่งจะต้องมีรหัสสินค้าและชื่อสินค้า Adapter ที่ทำหน้าที่นี้คือการใช้คำสั่ง SQL ของ PostgreSQL เพื่อโต้ตอบกับตารางข้อมูล

ในทางปฏิบัติ การเชื่อมต่อกับ PostgreSQL จะถูกห่อหุ้มไว้ใน Repository Layer ซึ่งทำหน้าที่เป็น Adapter ดังตัวอย่างโค้ดต่อไปนี้:

SQL

-- 1. สร้างตารางสินค้า (The Data Structure) --
CREATE TABLE products (
    product_id SERIAL PRIMARY KEY,
    sku VARCHAR(50) UNIQUE NOT NULL,
    product_name VARCHAR(255) NOT NULL,
    price NUMERIC(10, 2)
);

-- 2. Adapter Function: บันทึกข้อมูลสินค้าใหม่ (Implementing the Port)
-- ฟังก์ชันนี้คือ Adapter ที่ใช้ PostgreSQL เพื่อบันทึกข้อมูล
CREATE OR REPLACE FUNCTION save_product(
    p_sku VARCHAR, 
    p_name VARCHAR, 
    p_price NUMERIC
) RETURNS INTEGER AS $$
BEGIN
    INSERT INTO products (sku, product_name, price) VALUES (p_sku, p_name, p_price)
    RETURNING product_id;
END;
$$ LANGUAGE plpgsql;

-- 3. การเรียกใช้งาน Adapter (Calling the Port)
SELECT save_product('A101', 'Apple', 1.50);
SELECT save_product('B202', 'Banana', 0.75);
SELECT save_product('C303', 'Orange', 2.00);

ข้อดีในการใช้ Ports and Adapters กับ PostgreSQL

การแยกส่วนนี้ทำให้เกิดประโยชน์หลักๆ คือ:

  • Testability: เราสามารถทดสอบ Business Logic ได้อย่างสมบูรณ์โดยไม่ต้องเชื่อมต่อกับฐานข้อมูลจริง (Mocking the Port)
  • Maintainability: หากเราต้องการเปลี่ยนจาก PostgreSQL ไปใช้ฐานข้อมูล NoSQL อื่นๆ เราจะต้องแก้ไขเพียงแค่ Adapter Layer เท่านั้น ส่วน Business Logic หลักยังคงอยู่ครบถ้วน
  • Isolation: โลจิกทางธุรกิจของเราถูกปกป้องจากการเปลี่ยนแปลงของรายละเอียดการจัดเก็บข้อมูล

บทสรุป

Clean Architecture ด้วยแนวคิด Ports and Adapters ไม่ใช่แค่รูปแบบการออกแบบ แต่เป็นแนวคิดที่ช่วยให้ระบบของเรามีความยืดหยุ่นสูง เมื่อผนวกกับ PostgreSQL เราจะใช้ PostgreSQL เป็นเครื่องมือในการสร้าง Adapter ที่แข็งแกร่ง ทำให้แน่ใจว่าแกนหลักของแอปพลิเคชัน (Business Logic) จะเป็นอิสระจากรายละเอียดของฐานข้อมูล ทำให้ระบบของเราพร้อมสำหรับการขยายตัวและเปลี่ยนแปลงในอนาคตได้อย่างง่ายดาย