单例模式

单例模式的含义:

作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

单例模式的三个要素:

1. 保存类唯一实例的静态变量。

2. 构造函数和克隆函数必须是私有的,放在外部去实例化,这样就不存在单例模式的意义。

3. 提供一个可供外部访问的公共静态方法,这个方法返回该类的唯一实例。

单例模式的意义:

在 PHP 中的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免大量的 new 操作消耗的资源。而不完全是对系统资源的节省, 可以避免重复实例化,因为 PHP 每次实例化一个类之后都会清理掉对应的资源,当再次使用的时候又会在重新去实例化一次。

单例模式使用的场景:

1. 数据库操作,减少对数据路的 new 操作,从而减少内存资源和系统资源的消耗。

2. 配置资源的共享,在一个系统中,配置资源都是全局的,使用单例模式也可以减少每次去读取配置带来的内存和系统资源的消耗。

代码演示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?php

class Single

{

    public static $attribute = '';

    public static $instance = '';

    private function __construct($attribute = '个人技术')

    {

        self::$attribute = $attribute;

    }

    public static function getInstance($attribute = '我是编程浪子走四方1')

    {

        if (!(self::$instance instanceof self)) self::$instance = new self($attribute);

        return self::$instance;

    }

}

单例模式和非单例模式的区别:

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

class Single {

    public function index() {

        return '';

    }

}

$single1 = new Single();

$single2 = new Single();

var_dump($single1);

var_dump($single2);

if ($single2 === $single1) {

    echo "是同一个对象";

} else {

    echo "不是同一个对象";

}

// object(Single)#1 (0) {

// }

// object(Single)#2 (0) {

// }

// 不是同一个对象

class Single2 {

    // 1.声明一个静态属性,用户保存类的实例

    public static $instance;

    //3. 将构函数私有化,避免外部new(每new一次,就不是同一个实例)

    private function __construct() {

    }

    // 2.声明一个静态的公共方法,用户外部调用本类的实例

    public static function getInstance() {

        if (!(self::$instance instanceof self)) {

            self::$instance = new self;

        }

        return self::$instance;

    }

    //3. 克隆函数私有化,避免外部clone(每clone一次,就不是同一个实例)

    private function __clone() {

    }

}

$singleDemo1 = Single2::getInstance();

$singleDemo2 = Single2::getInstance();

var_dump($singleDemo1->getInstance());

var_dump($singleDemo2->getInstance());

if ($singleDemo1 === $singleDemo2) {

    echo "是同一个对象";

} else {

    echo "不是同一个对象";

}

// object(Single2)#3 (0) {

// }

// object(Single2)#3 (0) {

// }

// 是同一个对象

工厂模式

工厂模式的有含义:

负责生成其他对象的方法。简单的描述就是通过一个工厂类,去实例化其他类或者方法。

工厂模式的意义:

通过使用工厂模式,减少因为多处 new 同一个类,当这个类发生变法时,则需要多处修改。

代码演示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

class Factor

{

    public static function createDB()

    {

        echo '我生产了一个DB实例';

        return new DB;

    }

}

class DB

{

    public function __construct()

    {

        echo __CLASS__ . PHP_EOL;

    }

}

$db = Factor::createDB();

注册树模式

注册数的含义:

注册树就是将多个对象注册在一个对象池中,当我们需要使用时,直接从对象池获取即可。

注册数模式的优点:

单例模式解决的是如何在整个项目中创建唯一对象实例的问题,工厂模式解决的是如何不通过 new 建立实例对象的方法。

那么注册树模式想解决什么问题呢? 在考虑这个问题前,我们还是有必要考虑下前两种模式目前面临的局限。

首先,单例模式创建唯一对象的过程本身还有一种判断,即判断对象是否存在。存在则返回对象,不存在则创建对象并返回。

每次创建实例对象都要存在这么一层判断。

工厂模式更多考虑的是扩展维护的问题。

总的来说,单例模式和工厂模式可以产生更加合理的对象。怎么方便调用这些对象呢?

而且在项目内如此建立的对象好像散兵游勇一样,不便统筹管理安排啊。因 而,注册树模式应运而生。

不管你是通过单例模式还是工厂模式还是二者结合生成的对象,都统统给我 “插到” 注册树上。我用某个对象的时候,直接从注册树上取 一下就好。

这和我们使用全局变量一样的方便实用。 而且注册树模式还为其他模式提供了一种非常好的想法。

代码演示:

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

<?php

/**

 * 单例模式

 */

class Single

{

    public static $attribute = '';

    public static $instance = '';

    private function __construct($attribute = '个人技术')

    {

        self::$attribute = $attribute;

    }

    public static function getInstance($attribute = '个人技术1')

    {

        if (!(self::$instance instanceof self)) self::$instance = new self($attribute);

        return self::$instance;

    }

}

/**

 * 工厂模式

 */

class Factory

{

    public static function createObj()

    {

        return Single::getInstance('个人技术');

    }

}

/**

 * 注册模式

 * 含义:就是将对象放在一个对象池中,使用的时候直接去对象池查找.

 * 需要如下几个操作:

 * 1.注册

 * 2.存放对象池

 * 3.获取

 * 4.销毁

 */

Class Register

{

    // 用一个数组来当做对象池,键当做对象别名,值存储具体对象

    public static $objTree = [];

    // 将对象放在对象池

    public static function set($key, $val)

    {

        return self::$objTree[$key] = $val;

    }

    // 通过对象别名在对象池中获取到对象别名

    public static function get($key)

    {

        return self::$objTree[$key];

    }

    // 通过对象别名将对象从对象池中注销

    public static function _unset($key)

    {

        unset(self::$objTree[$key]);

    }

}

Register::set('single', Factory::createObj());

$single = Register::get('single');

print_r($single);

echo $single::$attribute;

详解 PHP 中的三大经典模式的更多相关文章

  1. 详解PHP中的三大经典模式

    单例模式 单例模式的含义: 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 单例模式 ...

  2. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  3. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  4. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...

  5. rsync的介绍及参数详解,配置步骤,工作模式介绍

    rsync的介绍及参数详解,配置步骤,工作模式介绍 rsync是类unix系统下的数据镜像备份工具.它是快速增量备份.全量备份工具. Sync可以远程同步,支持本地复制,或者与其他SSH.rsync主 ...

  6. 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)

    用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ...

  7. [转帖]【Oracle】详解Oracle中NLS_LANG变量的使用

    [Oracle]详解Oracle中NLS_LANG变量的使用 https://www.cnblogs.com/HDK2016/p/6880560.html NLS_LANG=LANGUAGE_TERR ...

  8. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  9. 详解Linux中的cat文本输出命令用法

    作系统 > LINUX >   详解Linux中的cat文本输出命令用法 Linux命令手册   发布时间:2016-01-14 14:14:35   作者:张映    我要评论   这篇 ...

随机推荐

  1. dapper之连接数据库(Oracle,SQL Server,MySql)

    因为项目需求,需要项目同时可以访问三个数据库,因此本人经过一番研究,得出以下代码. 1.建立公共连接抽象类(DataBase) public abstract class DataBase { /// ...

  2. 微信小程序如何发送订阅消息,正确姿势来了,建议收藏!

    小程序订阅消息公测已经有些日子,今天以世界上最好的语言(PHP)为例,说一下如何发送订阅消息. 1.订阅消息 其实如果用过模板消息的话,改用订阅消息挺简单的,看一下官方文档稍加摸索就能使用. 但是对于 ...

  3. 微服务架构 ------ Day01 微服务架构优缺点

    1. 微服务架构的优点 庞大的单体程序 -> 一套微型程序. 每一个服务有明确的边界(服务之间的消息通讯机制) ,每一个服务都能单独的开发和维护,并且更好理解 每一个服务都能由一个团队来开发,当 ...

  4. IOT设备的7大安全问题

    IOT设备的7大安全问题 串口安全 IOT设备一般包含各类串口,并且这些串口缺乏认证机制.一旦暴露给了hacker,hacker可以很容易的查找敏感信息和dump固件,从而导致各类安全问题.建议厂家在 ...

  5. 解决 Mybatis报错org.apache.ibatis.ognl.NoSuchPropertyException: XXXCriteria$Criterion.noValue

    问题 这个noValue一定存在,但是报错. 场景就是存在并发的情况下,尤其是在服务刚刚启动的时候,就会发生这个异常. 但是很不幸,mybatis 3.4.1之前,用的 OGNL都是由这个问题. 分析 ...

  6. Java内存模型(JMM)详解

    在Java JVM系列文章中有朋友问为什么要JVM,Java虚拟机不是已经帮我们处理好了么?同样,学习Java内存模型也有同样的问题,为什么要学习Java内存模型.它们的答案是一致的:能够让我们更好的 ...

  7. spring cloud 2.x版本 Eureka Server服务注册中心教程

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 1.创建服务注册中心 1.1 新建Spring boot工程:eureka-server 1 ...

  8. nginx基于uwsgi部署Django

    1.安装nginx yum install -y nginx(需要epel源) 2.安装uwsgi yum groupinstall "Development tools" yum ...

  9. mybatis-spring 启动过程和调用过程

    mybatis-spring 可以为我们做什么 mybatis框架已经很不错了,它把配置和执行sql的通用过程抽象出来.只要你符合mybatis框架的要求,首先有正确的配置,然后有model,inte ...

  10. Luogu P1098 字符串的展开

    这几天划了划水看了看初赛的试题,没写什么随笔. 今天刷刷洛谷试炼场.(不要问为什么我还在普及区) 题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串 ...