关于php:tp5源码分析第三步设计模式反射机制

设计模式

1.单例模式

单例模式首先要满足三个条件:1.领有一个构造函数,并且为private 2.领有一个动态成员变量用来放弃类的实例 3.领有一个拜访这个实例的静态方法。
单例模式一个类只有一个实例,并提供一个拜访它的全局拜访入口。单例模式是在你想管制实例数目,节俭系统资源的时候应用。例如以下场景中:
 1、一个党只能有一个书记。 2、Windows 是多过程多线程的,在操作一个文件的时候,就不可避免地呈现多个过程或线程同时操作一个文件的景象,所以所有文件的解决必须通过惟一的实例来进行。 3、一些设施管理器经常设计为单例模式,比方一个电脑有两台打印机,在输入的时候就要解决不能两台打印机打印同一个文件。
长处: 1、在内存里只有一个实例,缩小了内存的开销,尤其是频繁的创立和销毁实例(比方治理学院首页页面缓存)。 2、防止对资源的多重占用(比方写文件操作)。
咱们在extend目录下创立一个Single.php文件,以下是Single的内容。

咱们在index.php中创立一个getSingle办法

这时咱们发现,无论咱们调用多少次Single,new只执行一次。当$instance不存在的时候,就会new一个实例,当存在的时候就间接返回,最多执行一次new。
tp5框架用的单例模式在Container.php中,在thinkphp\library\think目录下。

2.注册树模式

注册树模式通过将对象实例注册到一颗全局的对象树上,须要的时候从对象树上采摘下来应用。
单例模式解决的是如何在整个我的项目中创立惟一对象实例的问题,工厂模式解决的是如何不通过new建设实例对象的办法。 那么注册树模式想解决什么问题呢? 在思考这个问题前,咱们还是有必要思考下前两种模式目前面临的局限。 首先,单例模式创立惟一对象的过程自身还有一种判断,即判断对象是否存在。存在则返回对象,不存在则创建对象并返回。 每次创立实例对象都要存在这么一层判断。 工厂模式更多思考的是扩大保护的问题。 总的来说,单例模式和工厂模式能够产生更加正当的对象。怎么不便调用这些对象呢?而且在我的项目内如此建设的对象如同散兵游勇一样,不便兼顾治理安顿啊。因 而,注册树模式应运而生。不论你是通过单例模式还是工厂模式还是二者联合生成的对象,都通通给我“插到”注册树上。我用某个对象的时候,间接从注册树上取 一下就好。这和咱们应用全局变量一样的不便实用。 而且注册树模式还为其余模式提供了一种十分好的想法。
接下来咱们进行注册树模式的实战解说,首先咱们在extend目录下创立一个TestRegister.php文件。在这个类外面咱们须要创立个注册树池子,而后创立几个办法,set()办法是把咱们的参数挂载在池子里,有两个参数,一个是$key,一个是$object。set办法的逻辑就是把$object填充到$objects[$key]中去。

get办法须要传入一个$key参数,咱们须要判断$objects[$key]中是否存在,如果不存在,就填入;如果存在就返回。

_unset办法同样传入$key参数,而后把$objects[$key]清空。

这就是一个简略的注册树模式的代码。残缺代码是这样的:

而后咱们进行应用层逻辑编写,同样在extend目录下创立一个A类,轻易输入点内容。

而后咱们在index.php外面创立一个办法,实例化A类,把A类挂在注册池外面。

如果咱们有多个相似于A的类,咱们就能够通过下面register办法一样去把它们挂在连接池外面。

依赖注入

依赖注入次要用来缩小代码间的耦合 无效拆散对象和它所需的内部资源,接下来咱们通过代码来对它进行了解。
首先咱们在extend目录下创立一个di目录,di目录里创立一个Person类,而后创立一个buy办法。接着再创立一个Car类,在外面创立一个pay办法,而后返回价格。在buy办法外面调用Car类外面的pay办法。


而后咱们在入口文件外面创立一个办法,而后调用Person类的buy办法。

这样就能够把Car类外面的pay办法调用了。这就是一个简略的依赖注入例子了。
其中Person类依赖于Car类,而后Car类注入到Person类中,因为person去买货色,不肯定要买Car,还有其余物品,这时就要把买的物品注入到Person类中去。这个时候问题来了,如果咱们buy的货色是其余物品,而不是Car,那咱们就要对代码进行批改了。批改如下:
首先把Person类外面的buy办法批改,之前咱们写的是指定的Car,这个时候咱们就要把指定的Car换成须要购买的物品,代码如下,间接传入对象,而后通过传入的对象进行调用。

在入口文件的办法中,咱们间接创立一个须要用到的实例,而后传给Person的办法。

这里我new了一个Car类,如果咱们须要的不是Car类,而是其余的类,那咱们就把Car换成须要的类。

反射机制

反射机制是在php5.0之后的版本减少的一个个性,这个个性给咱们提供了一个弱小的API,容许咱们在php运行环境中去拜访和应用类、办法、属性、参数和正文,它的性能是十分弱小的,常常用于高扩大的php框架,主动加载插件、生成文档。比如说咱们进行生成php外面的正文等,就是通过php里的反射机制进行的,甚至能够用来扩大php语言。反射机制外面有许多办法,咱们能够依据文档去查看各种办法的用处,文档链接:php反射机制链接。在咱们应用反射机制的时候,首先要对类进行实例化,而后实例化类的反射机制,接下来进行调用这些办法。

容器类简略实战

接下来咱们对下面的常识进行综合性的实际,创立一个简略的容器类。
咱们进行操作的文件有以下几个文件,首先是容器类Container,而后是Person类和Car类,最初是应用层index.php入口文件。
首先是容器类Container代码:

<?php
namespace di;
class Container
{
 /*
 * 存放数据的容器 * */ public $instances = [];
 /*
 * 容器中的对象实例 * */ protected static $instance;
 private function __construct()
 { } /*
 * 获取以后容器的实例(单例) * * */ public static function getInstance(){
 if (is_null(static::$instance)){
 static::$instance = new static;
 }
 return static::$instance;
 }
 public function set($key,$value){
 $this->instances[$key] = $value;
 }
 /*
 * 获取容器外面的实例  会用到反射机制 * */ public function get($key){
 if(!empty($this->instances[$key]))
 { $key = $this->instances[$key];
 }
 $reflect = new ReflectionClass($key);
 //获取类的构造函数
 $c = $reflect->getConstructor();
 if (!$c){
 return new $key;
 }
 $params = $c->getParameters();
//        dump($params);exit();
 if (empty($params)){
 return new $key;
 }else{
 foreach ($params as $param){
 $class = $param->getClass();
 if (!$class){
 }else{
 $args[] = $this->get($class->name);
 }
 } } return $reflect->newInstanceArgs($args);
 }
}

而后是Person代码

<?php
namespace di;
class Person
{
 public function __construct(Car $obj,$a = 124)
 { $this->obj = $obj;
 $this->a = $a;
 }
 /*
 * 依赖:Person类依赖于Car * 注入  Car类注入到Person * */ public function buy(){
 return $this->a . "|" . $this->obj->pay();
 }
}

Car代码

<?php
namespace di;
class Car
{
 public  function pay(){
 return 123;
 }
}

而后是index入口文件的办法代码:

public function buy(){
 Container::getInstance()->set("person","diPerson");
 Container::getInstance()->set("car","diCar");
 $obj = Container::getInstance()->get("person");
 dump($obj->buy());
}

其中Person、Car、Container都在extend目录下的di目录中。

以上就是容器类的简略实现。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理