Laravel Url 使用指南 4-3 使用 Presenter 管理 url

心智極客發表於2020-01-09

原文

原理

從單一職責的角度來看,url 可由專門的類管理,模型將 url 的生成職責委託給專門的類,使用如下

$post->presenter()->show();

這種設計模式稱之為委託模式,模型只需要關注結果,不需要關注 url 的具體生成過程。

實現

定義一個 UrlPresenter 類,用於管理 url 的生成

<?php

namespace App\Urls;

use Illuminate\Database\Eloquent\Model;

class UrlPresenter
{
    protected $model;

    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    public function __get($key)
    {
        if(method_exists($this, $key))
        {
            return $this->$key();
        }

        return $this->$key;
    }

    public function link(string $name, array $params = []) : string
    {   
        array_unshift($params, $this->model->getRouteKey());

        return route("{$this->model->getTable()}.$name", $params);
    }

    public function show(array $params = []) : string
    {
        return $this->link('show', $params);
    }

    public function edit(array $params = []) : string
    {
        return $this->link('edit', $params);
    }

    public function update(array $params = []) : string
    {
        return $this->link('update', $params);
    }

    public function delete(array $params = []) : string
    {
        return $this->link('destroy', $params);
    }
}

在 Model 中定義委託關係

// Post.php
public function presenter()
{
    return new \App\Urls\UrlPresenter($this);
}

使用

$post = Post::first();
$post->presenter()->show();
$post->presenter()->show;

封裝成 Trait

<?php

namespace App\Traits;

use App\Urls\UrlPresenter;

trait Presenterable
{
    public function presenter()
    {
        return new UrlPresenter($this);
    }
}

使用

// Post.php
use App\Traits\Presenterable;

class Post extends Model
{
    use Presenterable;
}

如果需要其他 Url,可以自定義 Presenter

<?php

namespace App\Urls;

class PostPresenter extends UrlPresenter
{
    public function markdown() 
    {
        return $this->link('markdown');
    }
}

使用

// Post.php
public function presenter()
{
    return new \App\Urls\PostPresenter($this);
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章