GORAGOD.com

GORAGOD.com

freelance, web developer, web designer, hosting, domain name

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 ได้ เพื่อให้สามารถเข้าถึงได้จากภายนอก
0SHAREFacebookLINE it!
^