什么是Laravel特质模式?

时间:2016-06-22 10:46:38

标签: laravel design-patterns dependency-injection laravel-5

在查看Laravel源代码时,我注意到很多这样的东西:

控制器类:

class Controller extends BaseController
{
    use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;
}

其中一个组成特征:

trait AuthorizesRequests {

    /**
     * Authorize a given action against a set of arguments.
     *
     * @param  mixed $ability
     * @param  mixed|array $arguments
     *
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function authorize($ability, $arguments = []) {
        list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
        return app(Gate::class)->authorize($ability, $arguments);
    }

    // ...

}

我对此有几个问题:

  • 此模式(将可重用的功能抽象为特征)是否具有名称?
  • 这种模式在任何其他项目中是否都有效?
  • 如果特征需要依赖关系,是否有最佳实践方法来注入它们,而不是使用服务定位器(在这种情况下为app())?

我正在考虑在我的代码中使用这种方法来分享我的几个类之间的一些通用功能 - 我正在考虑创建一个ChecksBarcodes特征,它将与股票信息库和共享一起使用这是一些类似但不相关的产品管理流程类之间的特征,它们都需要检查条形码。

2 个答案:

答案 0 :(得分:2)

特征与扩展类相似,但有一些差异

  • Traits没有构造函数
  • 类只能扩展一个类,但具有多个特征

它们与其他语言的mixins类似。我想你可以说它是一种简单的方法来使用DRY principle

由于traits没有构造函数,因此它们所使用的任何依赖项都需要存在于它们所使用的类上。我认为取决于课程,除了特质之外还有一些不好的设计模式。因此,您必须使用服务定位器来引入依赖关系。

如果您不想使用服务定位器,我建议使用类而不是特性。你可以有一个BarcodeChecker类,你可以将它注入你想要使用它的类的构造函数中。然后,您将使用$this->checkBarcode()而不是$this->barcodeChecker->check()。我认为如果特征需要依赖,这将是一个更好的设计模式。

答案 1 :(得分:1)

使用PHP 5.4引入的特性,通常解决PHP的一个大的问题:单继承。我粗略猜测:如果PHP支持多继承(从多个类继承),就不会有特征。

然而,特性是减少代码重复的好方法,并且为多个类提供相同的功能。

  • 据我所知,使用特征没有真正的(模式)名称。
  • 与其他软件设计模式相比,它本身不是模式,只需将其命名为 traits ;)
  • Laravel,也许更具体地说,Cashier包是使用特征的好例子。如果有人发现其他好例子,请提及。
  • 特征可以通过其他特征扩展。这当然会产生越来越多的复杂性。为了扩展你,你可能应该考虑其他方法来为你的类带来一个功能。特征的“链接”增加了复杂性。