ในฐานะ Senior Architect ด้านระบบ PHP การทำความเข้าใจ Design Patterns ไม่ใช่แค่การท่องจำโค้ด แต่คือการเรียนรู้ ‘วิธีแก้ปัญหา’ (Proven Solutions) ที่ผ่านการพิสูจน์แล้ว มันเปรียบเสมือนชุดเครื่องมือทางความคิดที่ช่วยให้เราเขียนโค้ดที่มีโครงสร้างชัดเจน, ยืดหยุ่นสูง (Flexible), และง่ายต่อการบำรุงรักษา (Maintainable) โดยเฉพาะอย่างยิ่งเมื่อระบบของเราต้องรองรับการขยายตัวและมีการเชื่อมต่อกับระบบฐานข้อมูลขนาดใหญ่ เช่น PostgreSQL
การใช้ Patterns อย่างถูกต้องจะช่วยให้เราหลีกเลี่ยงการเขียนโค้ดแบบ “God Object” และส่งเสริมหลักการ SOLID โดยเฉพาะ Single Responsibility Principle ทำให้เมื่อคุณต้องการเพิ่มฟีเจอร์ใหม่ เช่น การเปลี่ยนวิธีการประมวลผลคำสั่งซื้อ (Order Processing) คุณไม่ต้องไปแตะโค้ดส่วนอื่น ๆ ที่ทำงานอยู่แล้ว
1. Strategy Pattern: การกำหนดกลยุทธ์การทำงาน (Flexibility)
เมื่อคุณมีอัลกอริทึมหลายแบบที่สามารถสลับใช้ได้ตามบริบท เช่น การคำนวณภาษี หรือการเชื่อมต่อฐานข้อมูลด้วยวิธีการที่แตกต่างกัน (เช่น PDO หรือ PGSQL Extension) Strategy Pattern คือคำตอบที่ดีที่สุด
ในตัวอย่างนี้ เราจะจำลองการคำนวณราคาตามวิธีการชำระเงินที่หลากหลาย:
PHP
// 1. Interface/Abstract Class (Strategy) <code>
interface PaymentStrategy {
public function calculate(float $amount): float;
}
// 2. Concrete Strategies (Implementation) <code>
class CreditCardPayment implements PaymentStrategy {
public function calculate(float $amount): float {
// สมมติว่าบัตรเครดิตมีค่าธรรมเนียม 2%
return $amount * 1.02;
}
}
class CashPayment implements PaymentStrategy {
public function calculate(float $amount): float {
// เงินสดไม่มีค่าธรรมเนียม
return $amount;
}
}
// 3. Context (Client) <code>
class ShoppingCart {
private PaymentStrategy $strategy;
public function setStrategy(PaymentStrategy $strategy) {
$this->strategy = $strategy;
}
public function checkout(float $total): float {
return $this->strategy->calculate($total);
}
}
// Usage Example <code>
$cart = new ShoppingCart();
$cart->setStrategy(new CreditCardPayment());
$price1 = $cart->checkout(100.0);
$cart->setStrategy(new CashPayment());
$price2 = $cart->checkout(100.0);
// $price1 จะมากกว่า $price2
2. Factory Pattern: การสร้าง Object อย่างชาญฉลาด (Decoupling)
Factory Pattern ใช้เมื่อคุณไม่ต้องการให้โค้ดหลักของคุณรู้ว่าต้องสร้าง Object ชนิดใด แต่ต้องการให้มี ‘โรงงาน’ ที่รับผิดชอบการสร้าง Object นั้น ๆ โดยเฉพาะ เหมาะอย่างยิ่งในการจัดการ Connection Object ที่ต้องเลือกใช้ Driver ต่าง ๆ
PHP
class DatabaseFactory {
public static function createConnection(string $type): ?object {
if ($type === 'pgsql') {
// ในชีวิตจริงคือการสร้าง PDO object สำหรับ PostgreSQL
return new class { public function connect() { return 'Connected via PGSQL'; } };
} elseif ($type === 'mysql') {
return new class { public function connect() { return 'Connected via MySQL'; } };
} else {
return null; // ไม่รองรับ
}
}
}
// Usage Example <code>
$pgsqlConnection = DatabaseFactory::createConnection('pgsql');
if ($pgsqlConnection) {
echo $pgsqlConnection->connect(); // Connected via PGSQL
}
3. Singleton Pattern: การควบคุม Instance เดียว (Resource Management)
Singleton Pattern รับประกันว่าคลาสของคุณจะมี Instance ได้เพียงตัวเดียวเท่านั้น เหมาะสำหรับ Resource ที่มีค่าใช้จ่ายในการสร้างสูง หรือต้องมีการเข้าถึงสถานะร่วมกันทั่วทั้งระบบ เช่น Connection Pool หรือ Logger
PHP
class DatabaseConnection {
private static ?DatabaseConnection $instance = null;
private function __construct() {
// Logic สำหรับการเชื่อมต่อ PostgreSQL ครั้งแรก
echo "[INFO] Establishing single PostgreSQL connection...\n";
}
public static function getInstance(): DatabaseConnection {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function executeQuery(string $query): void {
echo "Executing query: " . substr($query, 0, 15) . "...\n";
}
}
// Usage Example <code>
$conn1 = DatabaseConnection::getInstance();
$conn2 = DatabaseConnection::getInstance();
// $conn1 และ $conn2 จะเป็น Object ตัวเดียวกัน
$conn1->executeQuery('SELECT 1, 2, 3');
บทสรุป: การเลือกใช้ Pattern ที่เหมาะสม
การเลือกใช้ Design Pattern ไม่ใช่การทำตามตำรา แต่คือการวิเคราะห์ปัญหา (Problem Analysis) ก่อนเสมอ: หากคุณต้องการความยืดหยุ่นในการสลับพฤติกรรม ให้ใช้ Strategy; หากคุณต้องการสร้าง Object ที่หลากหลายจากจุดเดียว ให้ใช้ Factory; และหากคุณต้องการควบคุม Resource ให้มี Instance เดียวเท่านั้น ให้ใช้ Singleton
การนำ Patterns เหล่านี้มาใช้ร่วมกับการจัดการ Resource ของ PostgreSQL อย่างถูกต้อง จะช่วยยกระดับโค้ด PHP ของคุณให้เป็นระดับ Enterprise-Grade อย่างแท้จริง