Singleton Pattern
Singleton เป็นรูปแบบหนึ่งของ design pattern ที่จะยอมให้ผู้ใช้สามารถสร้าง Object ได้เพียงหนึ่งเดียว (Single Instance) เท่านั้น ประโยชน์ของมันก็เช่น การสร้างไฟล์ตั้งค่าระบบ ซึ่งควรจะมีคุณสมบัติเหมือนๆกันในทุกๆที่ ที่เรียกใช้ ยกตัวอย่างปัญหาอันเกิดจากการสร้าง Object แบบปกติตามโค้ดด้านล่าง
ผลลัพท์
จากโค้ดด้านบน มีการสร้าง Instance ของ Cfg สองครั้งด้วยกันภายในคลาส A และ B และมีการแก้ไขค่า (property) โดยคลาส A แต่ผลลัพท์ไม่มีการเปลี่ยนแปลงไปถึงคลาส B (ยังคงมีค่าเดิม)
ในกรณีข้างต้น Singleton Pattern จะถูกใช้ในการแก้ปัญหานี้
คุณสมบัติของ Singleton Pattern
ผลลัพท์
อธิบายโค้ดของ Singleton กันหน่อย
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
- มีเพียง Instance เดียวเท่านั้น (Single Instance)
- ต้องสามารถเรียกใช้ได้จากทุกที่ (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 ได้ เพื่อให้สามารถเข้าถึงได้จากภายนอก