laravel(源码笔记)中间件解析过程

发布于:2024-03-23 ⋅ 阅读:(57) ⋅ 点赞:(0)

装饰器

1. 和继承对比:

  1. 嵌套方式,可控制添加行为的方法和时机

2. 实现:

1. Component抽象类,方便动态添加职责
2. ConcreteComponent Component的实现类
3. Decorator,装饰器的抽象类,接受Component,并维持这个实例,并且定义和component一致的接口。
4. ConcreteDecoratorA, ConcreteDecoratorB。装饰器的具体实现类。
5. 使用
 ```php
  $component = new ConcreteComponent();
	$decoratorA = new ConcreteDecoratorA($component);
	$decoratorB = new ConcreteDecoratorB($decoratorA);
	$decoratorB->operation();
 ```

3. 装饰模式需要注意的问题

一个装饰类的接口必须与被装饰类的接口保持相同,对于客户端来说无论是装饰之前的对象还是装饰之后的对象都可以一致对待。
尽量保持具体组件类ConcreteComponent的轻量,不要把主逻辑之外的辅助逻辑和状态放在具体组件类中,可以通过装饰类对其进行扩展。 
如果只有一个具体组件类而没有抽象组件类,那么抽象装饰类可以作为具体组件类的直接子类。

4. 适用环境

需要在不影响组件对象的情况下,以动态、透明的方式给对象添加职责。
当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时可以考虑使用装饰类。

中间件(理解洋葱模式的包装和解析过程)

  1. sendRequestThroughRouter
  2. then/getInitialSlice firstSlice = call_user_func($destination, $passable); 第一次循环
  3. return call_user_func(array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable);
  4. getSlice 是个闭包(重点理解这里,array_reduce函数,对getSlice()闭包不断解开,应用到pipes上)
  5. return call_user_func( s l i c e ( slice( slice(stack, $pipe), $passable),这句解开后其实就是父类的getSlice函数
  6. 父类getSlice 核心逻辑代码。
    1. 是闭包,返回对闭包调用请求
    2. 不是对象,解析中间件,得到中间件名称和参数,设置中间件为实例化的中间件,合并中间件参数到基本参数数组中作为最后的参数,进入步骤4(比如中间件为’throttle:60,1’)
    3. 其他,设置参数 p a r a m e t e r s = [ parameters=[ parameters=[passable(请求),$stack(每次请求的结果)] (可能为对象,直接调用就好)
    4. 调用中间的handle方法处理参数$parameters
  7. next的过程待补充