总结:
单例模式:一个类仅允许创建一个实例
例如:
1.一个站点仅连接一个数据库连接对象
2.一个站点仅允许存在一个配置类的实例对象
必须先声明一个静态私有属性:用来保存当前类的实例
1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享
2. 为什么必须是私有的?不允许外部直接访问,仅允许通过类方法控制方法
3. 为什么要有初始值null,因为类内部访问接口需要检测实例的状态,判断是否需要实例化
实例
<?php /** * 单例模式:一个类仅允许创建一个实例 * 例如: * 1.一个站点仅连接一个数据库连接对象 * 2.一个站点仅允许存在一个配置类的实例对象 * */ class Config1{} class Config { /** * 必须先声明一个静态私有属性:用来保存当前类的实例 * 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享 * 2. 为什么必须是私有的?不允许外部直接访问,仅允许通过类方法控制方法 * 3. 为什么要有初始值null,因为类内部访问接口需要检测实例的状态,判断是否需要实例化 */ private static $instance = null; private $setting = []; //构造器私有化:禁止外部访问 private function __construct(){} //克隆方法私有化 private function __clone(){} //因为用静态属性返回类实例,而只能在静态方法使用静态属性 //所以必须创建一个静态方法来生成当前类的唯一实例 public static function getInstance() { //检测当前类属性$instance是否已经保存了当前类的实例 if (self::$instance == null){ //如果没有,则创建当前类的实例 self::$instance = new self; } //如果已经有了当前实例,就直接返回,不用重复创建 return self::$instance; } //设置配置项 public function set($index,$value) { $this->setting[$index] = $value; } //读取配置项 public function get($index) { return $this->setting[$index]; } } $boj1 = new Config1; $boj2 = new Config2; var_dump($obj1,$obj2); echo '<hr>'; $obj1 = Config::getInstance(); $obj2 = Config::getInstance(); var_dump($obj1,$obj2); $obj1->set('host','127.0.0.1'); echo $obj1->get('host'); <?php /* * 单例模式:用于创建单一类型的唯一实例对象 * 工厂模式:用于创建多种类型的多个实例对象 */ //$obj = create($class); //根据类不同,生成不同形状的容器 //声明形状类 class Shape { //声明静态方法create,根据容器形状不同,创建不同图形类的实例 public static function create($type,array $size[]) { //检测形状 switch ($type) { case 'rectangle': return new Rectangle ($size[0],$size[1]) break; case 'triangle': return new Triangle ($size[0],$size[1]) break; } } } //声明长方形类 class Rectangle { private $width; private $height; public function __construct($width,$height) { $this->width = $width; $this->height = $height; } //计算长方形面积 public function area() { return $this->width * $this->height; } } //声明三角形 class Triangle { private $bottom; private $height; public function __construct($bottom,$height) { $this->bottom=$bottom; $this->height=$height; } public function area() { return ($this->bottom*$this->height)/2; } } //使用静态方法来实例化形状类,而不是用传统的new 关键字 //并根据形状类型参数的不同,来实例化不同的类,生成不同的对象 $rectangle = Shape::create('rectangle',[20,20]); echo '长方形面积是'.$rectangle.$rectangle->area(); $triangle = Shape::create('triangle',[20,50]); echo '三角形的面积是'.$triangle->area(); <?php /* * 注册树:其实就是创建一个对象集,也叫对象池,是用数组来进行存储的 * 原理非常的简单 */ //声明3个类 class Register { //静态属性保存着所有已经挂在树上的对象 public static $objs = []; //将对象挂在树上 public static function set ($index,$value) { self::objs[$index] = $objs; } //取出对象作用 public static function get($index) { return self::$objs[$index]; } //已经无效的对象,及时销毁。节省资源 public static function del($index) { unset(self::$objs[$index]); } } //先将3个实例化后挂到对象树上 Register::set('demo1',new Demo1); Register::set('demo2',new Demo2); Register::set('demo3',new Demo3); //检测是否上树 var_dump(Register::$objs); echo '<hr>'; echo '<pre>'.print_r(Register::$objs,true).'</pre>'; echo '<hr>'; //用注册类的get方法查看 var_dump(Register::get('demo2')); //删除对象池中的某个实例对象 Register::del('demo2'); //再次查看demo2对象,已经不能被查看了,因为被销毁了 var_dump(Register::get('demo2'));
运行实例 »
点击 "运行实例" 按钮查看在线实例