PHP中單例模式的思考
單例模式的要點有三個:
- 一是某個類只能有一個實例;
- 二是它必須自行創建這個實例;
- 三是它必須自行向整個系統提供這個實例。
/**
* 設計模式之單例模式
* $_instance必須聲明為靜態的私有變量
* 構造函數必須聲明為私有,防止外部程序new類從而失去單例模式的意義
* getInstance()方法必須設置為公有的,必須調用此方法以返回實例的一個引用
* ::操作符只能訪問靜態變量和靜態函數
* new對象都會消耗內存
* 使用場景:最常用的地方是數據庫連接。
* 使用單例模式生成一個對象后,該對象可以被其它眾多對象所使用。
*/
class man
{
//保存例實例在此屬性中
private static $_instance;
//構造函數聲明為private,防止直接創建對象
private function __construct()
{
echo '我被實例化了!';
}
//單例方法
public static function get_instance()
{
var_dump(isset(self::$_instance));
if(!isset(self::$_instance))
{
self::$_instance=new self();
}
return self::$_instance;
}
//阻止用戶復制對象實例
private function __clone()
{
trigger_error('Clone is not allow' ,E_USER_ERROR);
}
function test()
{
echo("test");
}
}
// 這個寫法會出錯,因為構造方法被聲明為private
//$test = new man;
// 下面將得到Example類的單例對象
$test = man::get_instance();
$test = man::get_instance();
$test->test();
// 復制對象將導致一個E_USER_ERROR.
//$test_clone = clone $test;
以上是我在網絡上看到的PHP單例模式的基本代碼。單例模式的主要作用是節省資源,禁止類被反復new。但是在PHP語言當中,根本不會存在這一情況。PHP腳本在每次運行完成后,會自動回收釋放的資源。如果你真的只需要實例化某個類一次,那么只要在之后的代碼中不再將其實例化就好。完全不需要在代碼層面上作出限制。與此同時,單例模式會讓單元測試和代碼維護的成本增高。
但這也并不意味著,單例模式百無一用。下面這段引用是我從Stackoverflow中看到的一段答案,讀完了之后發現很有趣也很諷刺。
you will find that very often something that you are absolutely sure that you'll never have more than one instance of, you eventually have a second ... When this happens, if you have used a static class you're in for a much worse refactor than if you had used a singleton ... it converts fairly easily to an intelligent factory pattern--can even be converted to use dependency injection without too much trouble. For instance, if your singleton is gotten through getInstance(), you can pretty easily change that to getInstance(databaseName) and allow for multiple databases--no other code changes.
不知道你是不是也很無語,單例模式最大的用出竟是是在當你需要一個以上的實例時讓代碼的修改更簡單化……