xiaohuihui
for me

PHP经典设计模式

2020-03-27 18:23:58
Word count: 1.2k | Reading time: 4min

PHP经典设计模式

单例模式:

单例模式是一种PHP常见的软件设计模式,单例单例,意思就是只有一个实例。单例模式确保某一个类只有一个实例,不能重复实例化,只能它自己实例化,而且内部自行实例化并向整个系统全局地提供这个实例。

因为主要要用到静态类,所以先普及一下静态类的特点:

静态方法只能访问静态成员,实例方法可以访问静态和实例成员。之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。同样,因为实例方法可以访问实例成员变量,如果允许静态方法调用实例方法,将间接地允许它使用实例成员变量,所以它也不能调用实例方法。基于同样的道理,静态方法中也不能使用关键字this。

为什么要使用单例模式?

当你定义了一个类的时候,它被实例化了一次,当其他人对它再次实例化的时候,还是返回第一次实例化的对象,可以避免大量的new操作,减少资源的消耗,接下来我将用代码进行演示单例类和常规类的区别。

PHP常规例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
class Obj
{
public $str = null ; //定义成员变量,给变量赋予空值

public function __construct()
{
$this->str = mt_rand(111,999); //随机生成其中的数字
}
}

$obj1 = new Obj(); //对类进行实例化
$obj2 = new Obj();
$obj3 = new Obj();

print_r($obj1);
print_r($obj2);
print_r($obj3);


?>

结果:

1

单例模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
class Obj
{
protected static $_Ins; //受保护的私有静态属性
public $str = null;

/*实例化类的时候,会自动调用类的构造方法,因此将构造方法设置为private属性,限制为只能在类内部实例化
定义类的私有构造方法,防止在类的外部实例化*/
private function __construct(){
$this->str = mt_rand(111,999);
}

//将克隆方法设置为私有,防止对象进行克隆
private function __clone()
{

}

/*定义一个静态方法,在类的内部实例化对象。实例化之前判断该类是否已经被实例化,如果被实例化,则return实例化对象,若没有实例化,便实例化一个对象并保存在类的静态属性中*/
public static function getInstance(){
if(!(self::$_Ins instanceof self)){
self::$_Ins = new self();
}
return self::$_Ins;
}
}



$obj1 = Obj::getInstance();
$obj2 = Obj::getInstance();
$obj3 = Obj::getInstance();

print_r($obj1);
print_r($obj2);
print_r($obj3);

?>

结果:

2

结果中,不同对象的输出是不一样的,所以也证实了单例模式的作用。

介绍单例模式是为下面的经典设计模式所做铺垫,一下代码所演示的类似与一个数据库的注册操作,对象就是每一个用户所注册的信息,而对象树就是所谓的数据库,用来存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
/***
* 单例模式
* 工厂模式
* 对象树
*/

//单例模式
class Site
{
//属性
public $siteName;
//本例的静态实例
protected static $instance = null;
//禁掉构造方法
private function __construct($siteName){
$this->siteName = $siteName;
}

//获取本类唯一实例
/**
* 定义一个静态方法,在类内部实例化对象。实例化前先判断该类是否已被实例化了,若已被实例化,就返回该实例化对象;若没被实例化,
* 便实例化一个对象并将该对象保存在类的静态属性中
* **/
public static function getInstance($siteName='大道至简'){
if(!self::$instance instanceof self){
self::$instance = new self($siteName);
}
return self::$instance;
}
}


//用工厂模式来生成本类的单一实例
class Factory
{
//创建指定类的实例
public static function create(){
return Site::getInstance('构造方法里面的方法'); //如果getInstance里没有参数,将默认指向原生方法里的参数
}

}


//对象注册数
/**
* 1.注册:set(),把对象挂到树上
* 2.获取:get(),把对象取下来
* 3.注销:_unset(),把对象吃掉
* **/
class Register
{
//创建对象池:数组
protected static $objects = [];
//生成对象并上树
public static function set($alias,$object){
self::$objects[$alias] = $object;
}

//从树上面取下对象
public static function get($alias){
return self::$objects[$alias];
}

//把树上的对象吃掉
public static function _unset($alias){
unset(self::$objects[$alias]);
}
}


//将Site类的实例上树,放到对象池
Register::set('site',Factory::create()); //调用工厂里的create()方法
//从树上去一个对象下来
$obj = Register::get('site');
//查看这个对象
var_dump($obj); //输出对象的相关信息
echo '<hr>';
echo $obj->siteName; //输出$siteName的值,优先工厂模式的值

3

< PreviousPost
容器和依赖注入
NextPost >
Kali渗透测试
CATALOG
  1. 1. PHP经典设计模式
    1. 1.0.0.1. 单例模式:
      1. 1.0.0.1.1. 因为主要要用到静态类,所以先普及一下静态类的特点:
      2. 1.0.0.1.2. 为什么要使用单例模式?