详解PHP中的三大经典模式
单例模式
单例模式的含义:
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
单例模式的三个要素:
1.保存类唯一实例的静态变量。
2.构造函数和克隆函数必须是私有的,放在外部去实例化,这样就不存在单例模式的意义。
3.提供一个可供外部访问的公共静态方法,这个方法返回该类的唯一实例。
单例模式的意义:
在 PHP 中的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免大量的 new 操作消耗的资源。而不完全是对系统资源的节省, 可以避免重复实例化,因为 PHP 每次实例化一个类之后都会清理掉对应的资源,当再次使用的时候又会在重新去实例化一次。
单例模式使用的场景:
1.数据库操作,减少对数据路的 new 操作,从而减少内存资源和系统资源的消耗。
2.配置资源的共享,在一个系统中,配置资源都是全局的,使用单例模式也可以减少每次去读取配置带来的内存和系统资源的消耗。
代码演示:
<?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 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 同一个类,当这个类发生变法时,则需要多处修改。
代码演示:
<?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 建立实例对象的方法。 那么注册树模式想解决什么问题呢? 在考虑这个问题前,我们还是有必要考虑下前两种模式目前面临的局限。 首先,单例模式创建唯一对象的过程本身还有一种判断,即判断对象是否存在。存在则返回对象,不存在则创建对象并返回。 每次创建实例对象都要存在这么一层判断。 工厂模式更多考虑的是扩展维护的问题。 总的来说,单例模式和工厂模式可以产生更加合理的对象。怎么方便调用这些对象呢?而且在项目内如此建立的对象好像散兵游勇一样,不便统筹管理安排啊。因 而,注册树模式应运而生。不管你是通过单例模式还是工厂模式还是二者结合生成的对象,都统统给我“插到”注册树上。我用某个对象的时候,直接从注册树上取 一下就好。这和我们使用全局变量一样的方便实用。 而且注册树模式还为其他模式提供了一种非常好的想法。
代码演示:
<?ph
/**
* 单例模式
*/
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中的三大经典模式的更多相关文章
- 详解 PHP 中的三大经典模式
单例模式 单例模式的含义: 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 单例模式 ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- 详解Android中的四大组件之一:Activity详解
activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
- rsync的介绍及参数详解,配置步骤,工作模式介绍
rsync的介绍及参数详解,配置步骤,工作模式介绍 rsync是类unix系统下的数据镜像备份工具.它是快速增量备份.全量备份工具. Sync可以远程同步,支持本地复制,或者与其他SSH.rsync主 ...
- 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)
用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ...
- [转帖]【Oracle】详解Oracle中NLS_LANG变量的使用
[Oracle]详解Oracle中NLS_LANG变量的使用 https://www.cnblogs.com/HDK2016/p/6880560.html NLS_LANG=LANGUAGE_TERR ...
- (转载)详解Javascript中prototype属性(推荐)
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- 详解Linux中的cat文本输出命令用法
作系统 > LINUX > 详解Linux中的cat文本输出命令用法 Linux命令手册 发布时间:2016-01-14 14:14:35 作者:张映 我要评论 这篇 ...
随机推荐
- 利用Helm简化Kubernetes应用部署(1)
目录 利用Helm简化Kubernetes应用部署 Helm基础 安装Helm 使用Visual Studio 2019为Helm编写一个简单的应用 利用Helm简化Kubernetes应 ...
- 集合线性表--List之ArrayList
集合操作——线性表 List: add().remove().subList().list.toArray().array.asList(). List排序: Collections.sort(li ...
- 用哈希算法的思想解决排序和字符串去重问题,时间复杂度为O(N)
第一个题目: int a[] = {12,13,12,13,19,18,15,12,15,16,17},要求对数组a进行排序,要求时间复杂度为O(N) 我们所知道的常规排序中,最优的解法也就是O(N* ...
- KafkStream架构
Kafka Stream 的整体架构图如下. 目前KafkaStream的数据源智能是如上图所示的Kafka,但是处理结果并不一定是如上图所示的输出到Kafka,实际上KStream和Ktable的实 ...
- DataTableHelper.cs 将DataTable转换为List,将List转换为DataTable的实现类
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Java应用在docker环境配置容器健康检查
在<极速体验docker容器健康>一文已体验了docker容器健康检查功能,今天就来给java应用的容器加入健康检查,使应用的状态随时都可以被监控和查看. 实战环境信息 操作系统:macO ...
- Hydra爆破神器使用
参数详解: -R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密码字典(文件)-e 空密码探测和指定用户密码探测 ...
- Cocos2d-x 学习笔记(11.6) Sequence
1. Sequence 动作序列.动作按参数顺序执行,动作总时长为每个动作的时长之和. 1.1 成员变量 FiniteTimeAction *_actions[]; float _split; // ...
- SSH框架项目配置和启动的加载顺序及请求的执行顺序
1:======配置和启动====== (1)配置web.xml 配置<context-param>,其中内容为Spring的配置文件applicationContext.xml.注意&l ...
- 算法问题实战策略 QUADTREE
地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...