使用 PHP Traits 來封裝 Laravel Eloquent 關聯關係

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

使用 Traits

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

相關文章
相關標籤/搜索