文章转发自专业的Laravel开发者社区,原始链接:https://learnku.com/laravel/t...
我最近在重构某个项目的代码,然后我发现自己在 Eloquent 模型上为了定义 Account 类的关联关系而在写同样的方法。另外仅供参考,我更偏向于使用 getters 和 setters 而不是直接访问魔术属性。
所以接下来我用一个 Post 模型来做演示,它看起来如下:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Post
*
* @package App
*/
class Post extends Model
{
/**
* @return string
*/
public function getTitle()
{
return $this->getAttribute('title');
}
/**
* @param string $title
* @return $this
*/
public function setTitle(string $title)
{
$this->setAttribute('title', $title);
return $this;
}
/**
* @return string
*/
public function getPost()
{
return $this->getAttribute('post');
}
/**
* @param string $post
* @return $this
*/
public function setPost(string $post)
{
$this->setAttribute('post', $post);
return $this;
}
/**
* @param Account $account
* @return $this
*/
public function setAccount(Account $account)
{
$this->account()->associate($account);
return $this;
}
/**
* @return Account|null;
*/
public function getAccount()
{
return $this->getAttribute('account');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function account()
{
return $this->belongsTo(Account::class, 'account_id', 'id');
}
}
我们定义了一些方法,一部分是为了 Post 属性,另一部分是为了关联关系。
现在,当我们再添加一个与 Account 有关联关系的模型时,我们又要添加同样的关联方法。这很费时间,而且如果你想修改这些方法,你还需要在所有有关联关系的模型上修改相应方法。
使用 Traits
Trait 的定义:
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。
这就是使用 traits 的完美理由。我们创建一个名为 HasAccountTrait 的 Trait,它将保存所有属于一个 account 的关系的所有方法:
<?php
namespace App;
/**
* Class HasAccountTrait
*
* @package App
*/
trait HasAccountTrait
{
/**
* @param Account $account
* @return $this
*/
public function setAccount(Account $account)
{
$this->account()->associate($account);
return $this;
}
/**
* @return Account|null;
*/
public function getAccount()
{
return $this->getAttribute('account');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function account()
{
return $this->belongsTo(Account::class, 'account_id', 'id');
}
}
然后我们使用 Trait 来重新整理一下上面的 Post 模型代码,所以它看起来像下面这样:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Post
*
* @package App
*/
class Post extends Model
{
use HasAccountTrait;
/**
* @return string
*/
public function getTitle()
{
return $this->getAttribute('title');
}
/**
* @param string $title
* @return $this
*/
public function setTitle(string $title)
{
$this->setAttribute('title', $title);
return $this;
}
/**
* @return string
*/
public function getPost()
{
return $this->getAttribute('post');
}
/**
* @param string $post
* @return $this
*/
public function setPost(string $post)
{
$this->setAttribute('post', $post);
return $this;
}
}
总结
使用 traits 意味着在定义同一个模型的关联关系时写出不重复的代码。它还可以加速开发,这取决于应用程序中有多少关联关系。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。