原理
從單一職責的角度來看,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 協議》,轉載必須註明作者和本文連結