文章轉發自專業的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