Singleton Pattern

Singleton เป็นรูปแบบหนึ่งของ design pattern ที่จะยอมให้ผู้ใช้สามารถสร้าง Object ได้เพียงหนึ่งเดียว (Single Instance) เท่านั้น ประโยชน์ของมันก็เช่น การสร้างไฟล์ตั้งค่าระบบ ซึ่งควรจะมีคุณสมบัติเหมือนๆกันในทุกๆที่ ที่เรียกใช้ ยกตัวอย่างปัญหาอันเกิดจากการสร้าง Object แบบปกติตามโค้ดด้านล่าง
class Cfg
{
    public $property = 1;
}

class A
{
    public $cfg;

    public function __construct()
    {
        $this->cfg = new Cfg;
    }
}

class B
{
    public $cfg;

    public function __construct()
    {
        $this->cfg = new Cfg;
    }
}
$a = new A;
$b = new B;
$a->cfg->property = 2;
echo $b->cfg->property;

ผลลัพท์
1

จากโค้ดด้านบน มีการสร้าง Instance ของ Cfg สองครั้งด้วยกันภายในคลาส A และ B และมีการแก้ไขค่า (property) โดยคลาส A แต่ผลลัพท์ไม่มีการเปลี่ยนแปลงไปถึงคลาส B (ยังคงมีค่าเดิม)

ในกรณีข้างต้น Singleton Pattern จะถูกใช้ในการแก้ปัญหานี้

คุณสมบัติของ Singleton Pattern
  1. มีเพียง Instance เดียวเท่านั้น (Single Instance)
  2. ต้องสามารถเรียกใช้ได้จากทุกที่ (Global Access)
class Cfg
{
    /**
     * @var Singleton สำหรับเรียกใช้ class นี้เพียงครั้งเดียวเท่านั้น
     */

    private static $instance = null;
    /**
     * property ของคลาส
     * 
     * @var int
     */

    public $property = 1;

    final private function __construct()
    {
        // do nothing
    }

    private function __clone()
    {
        // do nothing
    }

    private function __wakeup()
    {
        // do nothing
    }

    /**
     * เรียกใช้งาน Class แบบสามารถเรียกได้ครั้งเดียวเท่านั้น
     *
     * @return \static
     */

    public static function &getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }
        return static::$instance;
    }
}

class A
{
    public $cfg;

    public function __construct()
    {
        $this->cfg = Cfg::getInstance();
    }
}

class B
{
    public $cfg;

    public function __construct()
    {
        $this->cfg = Cfg::getInstance();
    }
}
$a = new A;
$b = new B;
$a->cfg->property = 2;
echo $b->cfg->property;

ผลลัพท์
2

อธิบายโค้ดของ Singleton กันหน่อย
  • อย่างแรกเลย เราจะไม่สร้างคลาสโดยใช้เมธอด new แต่จะเรียกใช้คลาสผ่าน getInstance แทน โดยในฟังก์ชั่นจะมีการตรวจสอบว่าเคยมีค่า $instance ($instance ต้องเป็น private เท่านั้น และต้องประกาศเป็น static ด้วย) หรือไม่ ถ้ามีจะไปเรียกเอาจาก instance เดิม ถ้าไม่มีให้สร้าง Instance ใหม่
  • เมธอด __construct, __clone และ __wakeup ถูกประกาศเพื่อป้องกันการเรียกใช้คลาสผ่านคำสั่ง new ด้วยการประกาศเป็น private
  • property ของคลาส สามารถประกาศเป็น public ได้ เพื่อให้สามารถเข้าถึงได้จากภายนอก
ผู้เขียน goragod โพสต์เมื่อ 04 ธ.ค. 2558 เปิดดู 5,023 ป้ายกำกับ design pattern
^