文章转发自专业的Laravel开发者社区,原始连接: https://learnku.com/laravel/t...
我最近在重构某个项目的代码,而后我发现本身在 Eloquent 模型上为了定义 Account 类的关联关系而在写一样的方法。另外仅供参考,我更偏向于使用 getters 和 setters 而不是直接访问魔术属性。php
因此接下来我用一个 Post 模型来作演示,它看起来以下:laravel
<?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 属性,另外一部分是为了关联关系。post
如今,当咱们再添加一个与 Account 有关联关系的模型时,咱们又要添加一样的关联方法。这很费时间,并且若是你想修改这些方法,你还须要在全部有关联关系的模型上修改相应方法。this
Trait 的定义:spa
Trait 是为相似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减小单继承语言的限制,使开发人员可以自由地在不一样层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减小复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。Trait 和 Class 类似,但仅仅旨在用细粒度和一致的方式来组合功能。 没法经过 trait 自身来实例化。它为传统继承增长了水平特性的组合;也就是说,应用的几个 Class 之间不须要继承。code
这就是使用 traits 的完美理由。咱们建立一个名为 HasAccountTrait 的 Trait,它将保存全部属于一个 account 的关系的全部方法:blog
<?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 意味着在定义同一个模型的关联关系时写出不重复的代码。它还能够加速开发,这取决于应用程序中有多少关联关系。ci