在选择使用钩子而不是使用中间件来实现诸如身份验证或缓存等功能时,是否有人可以解释是否存在任何明显的优点或缺点? 例如 - 我可以通过自定义中间件获取请求对象并设置应用程序语言变量来实现翻译功能,该变量可用于在应用程序执行时加载正确的翻译文件。或者我可以在路由之前添加一个钩子并读取请求变量,然后在应用程序执行期间加载正确的文件。 是否有任何明显的原因让我错过了一个选择比另一个更好的选择?
答案 0 :(得分:2)
据我所知,middleware
对于每个路由工作都是完美的。 hooks
最适合在整个应用程序范围内执行任何操作。对于您的情况,我认为使用hooks
比使用中间件更好。
答案 1 :(得分:0)
TL / DR; (简短答案)
当执行顺序很重要时,使用中间件。因此,通常在代码的各个方面将中间件添加到执行堆栈中(通常在引导过程中添加中间件,同时添加记录器,身份验证等。在大多数实现中,每个中间件功能随后都会确定执行是否继续。这往往会导致这样的错误,即所添加的中间件不会继续错误执行,或者改组了预期的顺序,或者只是忘记了添加中间件的位置或原因,因为几乎可以在任何地方添加中间件。很难追踪。
挂钩通常不知道执行顺序;每个挂钩函数都简单执行。执行任务的选择取决于功能本身。这要简单得多,并且活动部件更少,因此从统计上讲产生的错误更少。但是,要检测它是否应该运行,在钩子中包含其他状态非常重要,这样钩子就不会伸到应用程序中,并与它本身不相关的东西耦合在一起(这可能需要纪律来推理)好,但通常更简单)。同样,由于它们的简单性,往往会在代码的某些命名点处添加钩子,从而减少了可以存在钩子的区域(通常是单个位置)。在现实世界中,很少需要通过挂钩使用中间件。放弃后续功能很常见的这种用例之一就是访问控制/登录/等,这是路由器倾向于经常实现的。
通常,由于无法保证或考虑到钩子的顺序,因此更易于推理和存储钩子。由于钩子可以否定自身,因此钩子在计算上也等效,使得中间件仅是常见问题的一种编码样式或简写形式。
深潜
当今,建筑师通常认为中间件是一个糟糕的选择。中间件可能会带来噩梦,并且在调试中所付出的努力很少会被任何速记法宝所抵消。
中间件和挂钩(以及Mixins,Layered-config,Policy,Aspects等)都是design pattern的“策略”类型的一部分。
策略模式,因为只要涉及代码分支,它们就会被调用,因此可能是最常用的软件设计模式之一。
知识和策略模式的使用可能是检测开发人员技能水平的最简单方法。
每当您需要应用“如果...那么”类型的逻辑(可选的执行/分支)时,就会使用策略模式。
在一个软件上进行的计算思想实验越多,可以在头脑上减少更多分支,然后将其重构。这本质上是“方面代数”;构造问题的“骨骼”,或一遍又一遍地思考正在发生的事情,将程序简化为基本概念/第一原则。重构时,这些思想实验是建筑师花费最多时间的地方;找到共同的方面并减少不必要的复杂性。
降低emergence(在系统论中是本地语言,特别是对于软件,是在特殊层上应用配置而不是首先编写软件)和monads。
Monad倾向于将正在执行的操作抽象化到一个级别,如果开发人员不注意的话,它可能会增加代码执行时间。
Monads和Emergence都倾向于将问题抽象化,以便可以使用基本构造块来通用应用这些零件。理论上,使用Monads(适用于小型)和Emergence(适用于大型),可以从最少的零件中构建出任何复杂的软件。
毕竟,在重构中:“最容易维护的代码是不再存在的代码。”
功能和映射功能
一种持续降低复杂性的好方法是应用函子和映射函数。通常,函子也是实现分支的最快方法,它可以使编译器深入研究问题,从而可以以最佳方式优化事物。它们也非常易于推理和维护,因此,将工作留给一天并使用部分重构的应用程序提交更改几乎没有什么危害。
Functor的名字来自于数学(特别是类别理论,在该理论中,它们被称为映射在两个集合之间的函数)。但是,在计算中,函子通常只是以一种或另一种方式映射问题空间的对象。
关于什么是计算机科学中的函子或不存在函子,存在着很大的争论,但是按照定义,您只需要关心映射问题并将“ functor”用作临时函数的行为。思想支架,使您可以将问题抽象出来,直到它成为配置或实现的因素而不是代码为止。