【问题标题】:What is the Laravel trait pattern?什么是 Laravel 特征模式?
【发布时间】:2016-06-22 10:46:38
【问题描述】:

在查看 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 特征,它将与股票信息存储库一起使用,并共享该特征在几个类似但不相关的产品管理流程类之间,都需要检查条形码。

【问题讨论】:

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


    【解决方案1】:

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

    尽管如此,特征是减少代码重复并进一步为多个类提供相同功能的好东西。

    • 据我所知,使用特征没有真正的(模式)名称。
    • 它本身并不是一个模式,与其他软件设计模式相比,就叫它traits ;)
    • Laravel 和更具体的 Cashier 包是使用特征的好例子。如果有人找到其他好的例子,请提及。
    • 特征可以被其他特征扩展。这当然会产生越来越多的复杂性。要进行扩展,您可能应该考虑其他方法来为您的类带来功能。特征的“链接”增加了复杂性。

    【讨论】:

      【解决方案2】:

      特征类似于扩展类,但有一些不同

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

      它们类似于其他语言中的 mixin。我想你可以说这是使用DRY principle 的简单方法。

      由于特征没有构造函数,因此它们所具有的任何依赖项都需要存在于它们所使用的类上。我认为依赖于类来拥有特性以外的东西将是一个糟糕的设计模式。因此,您必须使用服务定位器来获取依赖项。

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

      【讨论】:

      • 您如何看待通过函数调用本身将依赖关系从类传递给特征? $this->checkBarcode($dependency, $barcode); 似乎是另一种可能性,但很笨拙。你同意吗?
      • 是的,这对我来说似乎没多大用处。如果你这样做,每个继承 trait 的类都需要手动注入依赖项,这违背了提取重复行为的目的。
      • 非常感谢您的想法杰夫。 @codedge,你们都回答了问题的不同部分,所以如果我能接受这两个答案,我会的!已选择接受另一个答案,因为它与问题的整体标题比依赖关系讨论更密切相关。
      猜你喜欢
      • 2021-12-18
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2018-09-17
      相关资源
      最近更新 更多