设计模式的定义
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性...
简而言之,就是前人总结的,大佬认可的,约定俗成的模式。好比“驼峰法”命名,你当然可以无视之(某些严格的框架除外),但如果遵循它,可以让你的开发工作更方便更高效。
设计模式有哪些
单例模式、工厂模式、注册树模式、策略模式、适配器模式、观察者模式......据我观察,互联网上有许多不同的提法。既然是前人总结的,而不是手册里规定的,大家各有各的说法,也能够理解。
(我在2022-10-14构建的PHP官方手册里没有搜索到“模式”和“单例”相关的词条。)
单例模式的目的
单例模式是指在内存中有且只会创建一次对象的设计模式,在程序中多次使用同一个对象且作用相同的时候,为了防止频繁的创建对象,单例模式可以让程序在内存中创建一个对象,让所有的调用者都共享这一单例对象。
比如:数据库连接设计,如果每次数据库操作就new一个新连接,性能开销成倍增加,反而可能连接过多导致服务器阻塞,降低了效率。
单例模式要点:三私一公
一私:私有的静态的保存对象的属性。
静态属性的特点是全局只有一个值(引用传递),一改则全改,能够保证对象属性的唯一性。
私有权限使对象属性不被类外调用,保证安全性。
二私:私有的构造方法(__construct)
我们知道,“构造方法的权限修饰符只能是public,否则无法创建对象”。因此,我们将其设为private,即可完全阻止类外部new对象。
三私:私有的克隆方法(__clone)
我们知道,创建对象有两种方式,new和clone,因此把克隆方法也设为private,类外就无法克隆对象,阻止了创建对象的可能。
一公:公共的静态的创建对象的方法
创建对象的方法必须公共权限,否则外部无法调用,连唯一的对象都无法创建,这个类就失去了意义。
单例模式案例之数据库连接
我们就在之前连接数据库的案例上加以修改,代码如下:
class Db
{
//私有的保存对象信息的静态属性
private static $obj = null;
//私有的数据库连接信息
private $Db_host;
private $Db_user;
private $Db_pswd;
private $Db_name;
private $link;
//私有的构造方法
private function __construct($config = array())
{
$this->Db_host = $config["Db_host"];
$this->Db_user = $config["Db_user"];
$this->Db_pswd = $config["Db_pswd"];
$this->Db_name = $config["Db_name"];
$this->connectDb();
$this->selectDb();
}
//私有的成员方法1
private function connectDb()
{
if (!$this->link = mysqli_connect($this->Db_host, $this->Db_user, $this->Db_pswd)) {
echo "连接数据库{$this->Db_host}失败,具体错误是:" . mysqli_connect_error();
die();
}
}
//私有的成员方法2
private function selectDb()
{
if (!mysqli_select_db($this->link, $this->Db_name)) {
echo "选择{$this->Db_host}数据库失败,具体错误是:" . mysqli_connect_error();
die();
}
}
//公共的析构方法
public function __destruct()
{
mysqli_close($this->link);
}
//私有的克隆方法
private function __clone()
{
}
//公共的静态的创建对象的成员方法:这个方法必须公共权限,否则外部无法创建唯一的对象
public static function startDb($config = array())
{
//判断obj对象是否存在,如果不存在就创建一个
if (!self::$obj instanceof self) {
self::$obj = new self($config);
}
return self::$obj;
}
}
;
$arr = array(
"Db_host" => "localhost",
"Db_user" => "username",
"Db_pswd" => "password",
"Db_name" => "DB_name"
);
$DB1 = Db::startDb($arr);//不是new对象,而是调用公共的静态的创建对象的成员方法