一  trait

  php是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性.

个人理解的trait是: trait = abstract class - interface,其中拥有interface的多个继承的性质.'继承'的方式是 use trait;

二  单例模式

  单例模式确保类在全局只能有一个实例,因为它的实例是由自己保存,在类的外部也无法对该类进行实例化.PHP的单例模式是为了避免重复创建对象带来的资源消耗.

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

实际项目中像数据库查询,日志输出,全局回调,统一校验等模块。这些模块功能单一,但需要多次访问,如果能够全局唯一,多次复用会大大提升性能。

  • 单例类只能有一个实例
  • 单例类必须自己创建自己的唯一实例
  • 单例类必须给所有其他对象提供这一实例

三   trait与单例模式结合使用

  3.1 简单demo

    

trait Singleton
{
private static $instance; static function getInstance(...$args)
{
if(!isset(self::$instance)){
self::$instance = new static(...$args);
}
return self::$instance;
}
} class MySingleton
{
use Singleton;
} $mySingleton = Mysingleton::getInstance();

  3.2 为什么不用 new self()

  new self() 和 new static 的区别: 只有在继承中才能体现出来、如果没有任何继承、那么二者没有任何区别 然后 new self() 返回的实列是不会变的,无论谁去调用,都返回的一个类的实列, 而 new static则是由调用者决定的。

  此处如果用new self() ,那么我们获取到的对象就不是MySingleton了

  3.3 类,基类,trait之间同名函数的优先级

  先说结论,类 > trait > 基类,简单实例:

<?php
trait Dog{
public $name="dog";
public function drive(){
echo "This is dog drive";
}
public function eat(){
echo "This is dog eat";
}
} class Animal{
public function drive(){
echo "This is animal drive";
}
public function eat(){
echo "This is animal eat";
}
} class Cat extends Animal{
use Dog;
public function drive(){
echo "This is cat drive";
}
}
$cat = new Cat();
$cat->drive();
echo "<br/>";
$cat->eat(); ?>
得出:

This is cat drive
This is dog eat

  3.4 特殊情况,基类use trait,本类不use

trait A{
private static $instance;
static function getInstance()
{
if(!isset(self::$instance)){
self::$instance = new static();
}
return self::$instance;
}
} class B{
use A;
function a()
{
var_dump('call at B');
}
} class C extends B{
function a()
{
var_dump('call at c');
parent::a();
}
} class D extends B{
use A;
function a()
{
var_dump('call at D');
parent::a();
}
}
$b = B::getInstance();
$c = C::getInstance();
$d = D::getInstance(); $c->a();
$d->a();
得出:

string(9) "call at B"
string(9) "call at D"
string(9) "call at B"

  此时我们与疑问了,根据3.2所写,调用者是 C::getInstance();  怎么$c->a();像变成了 $b->a();一样呢???
(个人观点,也验证了)其实这里的$c,就是class B

  接下来进行验证:

trait A{
private static $instance;
static function getInstance()
{
if(!isset(self::$instance)){
self::$instance = new static();
}
return self::$instance;
}
} class B{
use A;function h(){
var_dump('h call at b');
} } class C extends B{function h(){
var_dump('h call at c');
}
}$b = B::getInstance();
$c = C::getInstance();$c->h();
得出:

string(11) "h call at b" 

  而我们去掉 class c 中的 h(), 会没有打印,验证了 这里的$c,就是class B 这句话.

  本篇就讲这么多,有兴趣的可以更深入了解trait与单例模式的知识点.

PHP trait与单例模式 (一次编写,到处使用)的更多相关文章

  1. 面试突击(六)——JVM如何实现JAVA代码一次编写到处运行的?

    声明:本文图片均来自网络,我只是进行了选择,利用一图胜千言的力量来帮助自己快速的回忆相关的知识点 JVM是 JAVA Virtual Machine 三个英文单词的首字母缩写,翻译成中文就是Java虚 ...

  2. 单例模式与pickle模块

    目录 设计模式之单例模式 pickle模块 设计模式之单例模式 设计模式是前辈们发明的经过反复验证用于解决固定问题的固定套路,在IT行业中设计模式总共有23种,可以分为三大类:创建型.结构型.行为型. ...

  3. golang面试-代码编写题1-14

    目录 1.代码编写题--统计文本行数-bufio 2.代码编写题--多协程收集错误信息-channel 3.代码编写题--超时控制,内存泄露 4.代码编写题--单例模式 5.代码编写题--九九乘法表 ...

  4. 很多个java面试题

    1. 为什么说Java是一门平台无关语言? 平台无关实际的含义是“一次编写到处运行”.Java 能够做到是因为它的字节码(byte code)可以运行在任何操作系统上,与底层系统无关. 2. 为什么 ...

  5. React Native:使用 JavaScript 构建原生应用

    [转载] 本篇为联合翻译,译者:寸志,范洪春,kmokidd,姜天意 数月前,Facebook 对外宣布了正在开发的 React Native 框架,这个框架允许你使用 JavaScript 开发原生 ...

  6. 【Spring】Spring AOP实现原理

    Spring AOP实现原理 在之前的一文中介绍过Spring AOP的功能使用,但是没有深究AOP的实现原理,今天正好看到几篇好文,于是就自己整理了一下AOP实现的几种方式,同时把代理模式相关知识也 ...

  7. 11.安装KVM虚拟机

    安装KVM虚拟机是一大难题,不按照虚拟机物理机128G内存和强劲的CPU无法充分利用.也不便于后面的jenkins自动部署.安装KVM虚拟机过程我是借鉴了网上下载的马哥linux   KVM那块的内容 ...

  8. 深入浅出 React Native:使用 JavaScript 构建原生应用

    深入浅出 React Native:使用 JavaScript 构建原生应用 链接:https://zhuanlan.zhihu.com/p/19996445 原文:Introducing React ...

  9. Java学习笔记之:Java简介

    一.引言 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称.由James Gosling和同事们共同研发,并在1995年正式推出. ...

随机推荐

  1. Burp的XSS插件

    xss工具burpXSSVALIDIRTOR(XSS自动扫描) 第一步 安装环境 Phantomjs下载:http://phantomjs.org/download.html 下载后配置环境变量,把b ...

  2. QBXT七月D1

    今天是lyd神仙讲课的第一天,可以感觉到的是这位神仙有着不同于他人的气质,比如他的表情包(雾) 好了来讲正经的) 今天讲的比较多的是模拟算法和一些比赛中的好习惯 high-level 这个名词的大体意 ...

  3. 浏览器端-W3School-HTML:HTML DOM Meta 对象

    ylbtech-浏览器端-W3School-HTML:HTML DOM Meta 对象 1.返回顶部 1. HTML DOM Meta 对象 Meta 对象 Meta 对象代表 HTML 的 一个 & ...

  4. Origin 2017 给曲线加标记符号

    最近在用Origin 2017画曲线图,需要给图像得曲线加上不同得标记符号用以区分,把操作步骤记录下来,免得忘了. 1.用Origin 2017打开一个曲线图,在任意一条曲线上点击右键弹出菜单,选择[ ...

  5. Oracle非分区索引,全局分区索引和本地分区索引。

    1.如果按照索引是否分区作为划分依据,Oracle 的索引类型可以分为非分区索引,全局分区索引和本地分区索引. 2.创建演示实例 --创建非分区表create table test_partition ...

  6. Computer Network Homework2’s hard question

    Computer Network Homework2’s hard question 2. What is the signal which is used to modulate the origi ...

  7. loadrunner设置Analysis分析时去掉思考时间

    在进行对loadrunner进行执行脚本的情况下,那么就需要在脚本中进行添加为思考时间,这样才更符合人为的脚本时间,那么在进行执行压力的过程中,思考时间是需要开启的,完成之后为了便于分析那么就需要把思 ...

  8. linux(centOS7)的基本操作(六) 进程管理

    进程的概念 1. 在linux系统中,每一段执行的程序都称为一个进程,被分配一个进程编号(id). 2. 每个进程都对应一个父进程,一个父进程可以复制多个子进程. 3. 一个进程可能以两种方式存在:前 ...

  9. OpenStack 虚拟机的磁盘文件类型与存储方式

    目录 文章目录 目录 虚拟机的磁盘文件类型 虚拟机磁盘文件的存放方式 QCOW2 镜像格式与 qemu-img 指令 参考文章 虚拟机的磁盘文件类型 Nova 虚拟机的虚拟磁盘主要包含有 Root D ...

  10. 微信小程序组件篇实战

    实现效果如下: 实现代码如下: index.wxml: <!--index.wxml--> <view class="container"> <vie ...