0x01 基础设计模式
参考大话PHP设计模式 。
单例模式
单例模式就是只有一个实例化存在。
- 拥有一个构造函数,并且为private
- 拥有一个静态成员变量用来保持类的实例
- 拥有一个访问这个实例的静态方法
1 |
|
这是后只能访问一次构造函数,因此只有一个实例。这里的实例化方法isInstance
和标量$is_instance
都要是静态方法。(为了防止实例化,isInstance
静态方法,这时候要用$is_instance
也是没有被实例化的静态方法)。
工厂模式
如果一个类名进行了修改, 使用工厂模式不用把每一处的new都修改, 而是直接修改工厂方法即可。作为一个统一的调度。
1 |
|
引入了工厂模式,我们不需要在业务层去修改代码了。这样有利于整个软件框架稳定,比如在model层调用不同的Driver实例化。使用工厂模式只要在工厂中选择想使用的数据库Driver就可以实现切换。
思想就是业务层不用new具体的类了,而是调用统一接口。由接口new并返回。工厂模式是许多高级模式里惯用的模式,如注册树模式。
注册树模式
注册树模式通过将对象实例注册到一棵全局的对象树上, 需要的时候从对象树上采摘下来使用。
一个软件的底层有许多不同的类库, 在业务层, 我们要调用这些类库的使用。 这些底层类很乱不便于管理,这里就使用注册树模式,便于管理。(类似于配置函数生成的配置静态变量,这种操作应用于类上)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class regTree{
//注册树池子
protected static $objects = null;
//挂载
public static function _set($key, $object){
self::$objects[$key] = $object;
}
//获取
public static function _get($key,){
if (!isset(self::$objects[$key]))
{
self::$objects[$keys] = new $key;
}
return self::$objects[$key];
}
//注销
public static function _unset($key){
unset(self::$objects[$key]);
}
}此时我们需要使用底层函数的时候就不需要去new了,而是像读配置一样,去注册树这个
配置数组
中去读。set:
$a =new target();
regTree::_set('target', $a);
get:
$target = regTree::_get('target');
简单的思想,大概就是这样了。。。
0x02 容器
TP5的容器类位于think/thinkphp/librarythink/Container.php
1 | use ArrayAccess; |
这里可以看出使用了反射机制。还使用了一堆PHP的内置接口。
看类声明:
1 | class Container implements ArrayAccess, IteratorAggregate, Countable |
ArrayAccess
: 像数组一样使用对象IteratorAggregat
: 聚合式的迭代器Countable
: 用来统计对象中某个元素的个数
往下:
1 | /** |
一看就像个单例模式,注册树的套路。
往下:
1 | /** |
一个映射关系, 为容器标识别名。
1 | /** |
看入口文件:
1 | Container::get('app')->path(__DIR__ . '/application/')->initialize(); |
这个地方就是静态调用Container
里的get方法:
1 | /** |
看第一个参数, 传入以后,调用单例模式得到一个容器对象, 然后调用make方法。重点环节:
1 | /** |
看类反射的具体逻辑:
1 | /** |