将特征用于服务层:这是不好的做法吗?
Using traits for service layer: is it bad practice?
我注意到 laravel 程序员使用 traits 在控制器中实现某种依赖注入是很常见的,而且 laravel 本身也使用很多 traits 来实现它似乎我,待服务。
我来自 symfony,其中 traits 并没有被框架本身广泛使用,我发现它有点奇怪,因为我发现使用 trait 是出于这样的原因,而不是那么清晰的设计。服务不应该在它们自己的 类 中定义吗?将特征用于服务是否可以接受?
一个trait类似于一个抽象的class,它不能被自己实例化。
Traits is a mechanism for code reuse in single inheritance languages
in this case PHP.
现在每当您发现自己的模型变得过于臃肿并且您在不同的模型中一遍又一遍地使用相同的功能时,您可能会认为这是使用特征的尾巴标志。
现在您可能会想,既然我们具有相同的功能,为什么不使用模板 design pattern 呢?!然而,由于 Laravel 中的所有模型都扩展了一个基本模型,所以你真的应该小心使用中间件。
Laravel 默认情况下使用很多特征示例,如果你想使用 softDeletes()
那么你只需拉一个特征来为该模型带来功能。
这里是 trait 的实际使用。我的一个应用程序碰巧想跟踪我的数据库上发生的所有更新并将它们存储在不同的 table 中。所以如果我想跟踪模型 activity 那么我只需使用这个特征:
<?php
namespace App;
use App\Activity;
trait RecordsActivity
{
protected static function bootRecordsActivity()
{
static::created(function ($thread) {
$thread->recordActivity('created');
});
}
protected function recordActivity($event)
{
Activity::create([
'user_id' => auth()->id(),
'type' => $event . '-' . strtolower((new \ReflectionClass($this))->getShortName()),
'subject_id' => $this->id,
'subject_type' => get_class($this),
]);
}
}
所以每当我想跟踪一个模型时 activity 我只需引入这个特征,
use RecordsActivity;
而不是用额外的代码甚至是不同模型中最糟糕的重复代码来使模型膨胀,或者使用 class 继承使其变得更加spageti。
或者在 Laravel 中的某些内置特征中,当您需要像 softDeletes 这样的特征时,您只需将它们拉入,而不是在基础 class 中准备好它们,即使您不需要它们.
我注意到之前的答案还没有被接受,所以我想给自己 2 美分。
我也来自 Symfony 2 环境,目前正在参与 Laravel 并为 Symfony 3 环境做准备我也在阅读这个主题,因为我曾经读到过特质是邪恶的。以下 link 有一个公认的答案,在我看来这是一个不太主观的答案,它做出了一些合理的假设并且看起来构造得很好:https://codereview.stackexchange.com/questions/74077/trait-accessing-variables-of-classes-using-it
但是,我认为对您来说最大的区别可能是默认的 Laravel 使用 ActiveRecord,这与 Symfony 使用的 Service/Repository 层形成对比。我个人更喜欢后者,它不那么重,更容易成为 SOLID,逻辑和数据通常已经解耦,使得层更容易交换。无论如何,这是一个不太切合主题且非常个人化的笔记。
现在在 Laravel 工作了几个月(相比之下,我在 sf2(和 sf1)工作了多年)我几乎不是 Laravel 工作原理的专家。就我个人而言,我仍然不喜欢 traits,因为它们对我来说太神奇了,如果你至少不连接它们的话。我经常认为通过其他设计模式可以更好地处理它。
TL;DR:(link 的主要内容)
- 特征的一个很好的用例是水平缩放,支持独立的动作,而无需在每次添加接口时都必须实现它的开销。 (通常这是相当简单的逻辑)
- 一个坏的特征是使用超出其自身范围的信息(例如 'main' 对象的属性,或简单的全局状态)或 enforces/breaks 契约。
我注意到 laravel 程序员使用 traits 在控制器中实现某种依赖注入是很常见的,而且 laravel 本身也使用很多 traits 来实现它似乎我,待服务。
我来自 symfony,其中 traits 并没有被框架本身广泛使用,我发现它有点奇怪,因为我发现使用 trait 是出于这样的原因,而不是那么清晰的设计。服务不应该在它们自己的 类 中定义吗?将特征用于服务是否可以接受?
一个trait类似于一个抽象的class,它不能被自己实例化。
Traits is a mechanism for code reuse in single inheritance languages in this case PHP.
现在每当您发现自己的模型变得过于臃肿并且您在不同的模型中一遍又一遍地使用相同的功能时,您可能会认为这是使用特征的尾巴标志。
现在您可能会想,既然我们具有相同的功能,为什么不使用模板 design pattern 呢?!然而,由于 Laravel 中的所有模型都扩展了一个基本模型,所以你真的应该小心使用中间件。
Laravel 默认情况下使用很多特征示例,如果你想使用 softDeletes()
那么你只需拉一个特征来为该模型带来功能。
这里是 trait 的实际使用。我的一个应用程序碰巧想跟踪我的数据库上发生的所有更新并将它们存储在不同的 table 中。所以如果我想跟踪模型 activity 那么我只需使用这个特征:
<?php
namespace App;
use App\Activity;
trait RecordsActivity
{
protected static function bootRecordsActivity()
{
static::created(function ($thread) {
$thread->recordActivity('created');
});
}
protected function recordActivity($event)
{
Activity::create([
'user_id' => auth()->id(),
'type' => $event . '-' . strtolower((new \ReflectionClass($this))->getShortName()),
'subject_id' => $this->id,
'subject_type' => get_class($this),
]);
}
}
所以每当我想跟踪一个模型时 activity 我只需引入这个特征,
use RecordsActivity;
而不是用额外的代码甚至是不同模型中最糟糕的重复代码来使模型膨胀,或者使用 class 继承使其变得更加spageti。
或者在 Laravel 中的某些内置特征中,当您需要像 softDeletes 这样的特征时,您只需将它们拉入,而不是在基础 class 中准备好它们,即使您不需要它们.
我注意到之前的答案还没有被接受,所以我想给自己 2 美分。
我也来自 Symfony 2 环境,目前正在参与 Laravel 并为 Symfony 3 环境做准备我也在阅读这个主题,因为我曾经读到过特质是邪恶的。以下 link 有一个公认的答案,在我看来这是一个不太主观的答案,它做出了一些合理的假设并且看起来构造得很好:https://codereview.stackexchange.com/questions/74077/trait-accessing-variables-of-classes-using-it
但是,我认为对您来说最大的区别可能是默认的 Laravel 使用 ActiveRecord,这与 Symfony 使用的 Service/Repository 层形成对比。我个人更喜欢后者,它不那么重,更容易成为 SOLID,逻辑和数据通常已经解耦,使得层更容易交换。无论如何,这是一个不太切合主题且非常个人化的笔记。
现在在 Laravel 工作了几个月(相比之下,我在 sf2(和 sf1)工作了多年)我几乎不是 Laravel 工作原理的专家。就我个人而言,我仍然不喜欢 traits,因为它们对我来说太神奇了,如果你至少不连接它们的话。我经常认为通过其他设计模式可以更好地处理它。
TL;DR:(link 的主要内容)
- 特征的一个很好的用例是水平缩放,支持独立的动作,而无需在每次添加接口时都必须实现它的开销。 (通常这是相当简单的逻辑)
- 一个坏的特征是使用超出其自身范围的信息(例如 'main' 对象的属性,或简单的全局状态)或 enforces/breaks 契约。