1. Giới thiệu
Singleton là pattern đảm bảo việc một ứng dụng trong một thời điểm chỉ được phép có duy nhất một thực thể của đối tượng Singleton. Có nghĩa là việc khởi tạo đối tượng chỉ duy nhất một lần đầu tiên, các lần sau, nó không được khởi tạo mới mà chính là đối tượng cũ. Điều này giúp tiết kiệm bộ nhớ và ngăn chặn việc tạo ra nhiều lần khởi tạo đối tượng.
2. Khi nào sử dụng
Khi trong ứng dụng có những thực thể bị truy xuất nhiều lần nhưng không cần thiết phải khởi tạo lại. Ví dụ:
- Database connect: nếu không dùng Singleton, mỗi lần muốn thao tác với Database, chúng ta cần phải khởi tạo lại lớp Database.
- Logger: trong ứng dụng, có nhiều chỗ cần phải lưu log, hãy tưởng tượng nếu không dùng Singleton, mỗi lần muốn lưu log lại phải khởi tạo lại lớp Logger.
- Đọc config file: bạn có một file chứa nhiều thông số config. Nếu không dùng Singleton, mỗi lần muốn đọc một thông số nào đó, bạn lại phải khởi tạo lại.
3. Xây dựng
Để xây dựng Singleton, bạn cần đáp ứng được các yêu cầu sau:
- Define thuộc tính (biến) private static instance
- Define public static function getInstance() trả về instance theo dạng lazy initialization (khởi tạo trong lần đầu).
- Define __construct() thành protected hoặc private để ngăn người dùng khởi tạo trực tiếp.
class Singleton
{
private static $instance;
private function __construct()
{
}
public static function getInstance()
{
if (null === static::$instance) {
static::$instance = new static;
}
return static::$instance;
}
}
4. Ví dụ
Để dễ hiểu chúng ta sẽ đi vào tìm hiểu một ví dụ cụ thể như sau: Giả sử bạn đang lập trình một ứng dụng web có sử dụng một database để lưu trữ dữ liệu. Việc kết nối tới database server được thông qua một class có tên là DatabaseManager
class DatabaseManager
{
private static $instance = null;
private $conn;
private $host = 'localhost';
private $user = 'root';
private $pass = '';
private $name = 'test';
private function __construct()
{
$this->conn = new PDO("mysql:host={$this->host};
dbname={$this->name}", $this->user, $this->pass,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES \'utf8\'"));
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new DatabaseManager();
}
return self::$instance;
}
public function getConnection()
{
return $this->conn;
}
}
Vì chúng ta sử dụng một lớp kiểm tra nếu một kết nối đã tồn tại trước khi nó thiết lập một kết nối mới, nó thực sự không quan trọng bao nhiêu lần chúng ta tạo một đối tượng mới ra khỏi lớp, chúng ta vẫn nhận được kết nối tương tự.
$instance = DatabaseManager::getInstance(); $conn = $instance->getConnection(); var_dump($conn); $instance = DatabaseManager::getInstance(); $conn = $instance->getConnection(); var_dump($conn); $instance = DatabaseManager::getInstance(); $conn = $instance->getConnection(); var_dump($conn);
5. kết luận
Singleton pattern là design pattern tương đối đơn giản, nhưng việc áp dụng khá hiệu quả, nó tạo ra một thực thể duy nhất để sử dụng, giúp tối ưu hóa việc sử dụng tài nguyên để chạy ứng dụng.









(5 lượt thả tim)



