antennaio/laravel-vo

充分利用Laravel中的值对象

v0.0.1 2016-04-11 12:15 UTC

This package is not auto-updated.

Last update: 2024-09-20 19:19:56 UTC


README

充分利用Laravel中的值对象

这是一个简单的ValueObject抽象类和ValueObjectCollection类,可以帮助您充分利用Laravel中的值对象。

安装

通过composer安装

composer require antennaio/laravel-vo:~0.0.1

用法 - ValueObject

以下是一个简单的领域值对象示例

use Antennaio\VO\ValueObject;
use InvalidArgumentException;

class Domain extends ValueObject
{
    protected function validate($value)
    {
        if (!preg_match('/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/', $value)) {
            throw new InvalidArgumentException('Domain is invalid: '.$value);
        }
    }
}
class MyModel extends Model
{
    ...

    public function getDomainsAttribute($domain)
    {
        return new Domain($domain);
    }

    public function setDomainAttribute(Domain $domain)
    {
        $this->attributes['domain'] = $domain;
    }
}

现在每当设置domain属性时,您需要传递一个Domain对象

$myModel = new MyModel;
$myModel->domain = new Domain('google.com');

以真正DRY的风格,值对象可以用于在请求中执行验证

Validator::extend('domain', function ($attribute, $value, $parameters, $validator) {
    try {
        new Domain($value);
    } catch (InvalidArgumentException $e) {
        return false;
    }

    return true;
});

使用自定义验证器验证domain字段

use App\Http\Requests\Request;

class SampleRequest extends Request
{
    ...

    public function rules()
    {
        return ['domain' => 'required|domain'];
    }
}

用法 - ValueObjectCollection

有时将多个值对象一起收集和存储非常有用。这时ValueObjectCollection就派上用场了。创建不可变的ValueObjectCollection就像告诉它哪些值对象将成为集合的一部分一样简单。

class DomainCollection extends ValueObjectCollection
{
    protected $valueObject = Domain::class;
}
class MyModel extends Model
{
    ...

    public function getDomainsAttribute($domains)
    {
        return new DomainCollection(unserialize($domains));
    }

    public function setDomainsAttribute(DomainCollection $domains)
    {
        $this->attributes['domains'] = serialize($domains->toArray());
    }
}

在下面的示例中,DomainCollection将接受有效的域名或抛出InvalidArgumentException

$myModel = new MyModel;
$myModel->domains = new DomainCollection(['google.com', 'amazon.com']);

// nah - InvalidArgumentException thrown
$myModel->domains = new DomainCollection(['google.com', 'amazon']);

通常,集合是由用户输入创建的,这就是为什么您也可以传递一个字符串,该字符串将在创建新集合时进行解析

$myModel = new MyModel;
$myModel->domains = new DomainCollection('google.com, amazon.com');

分隔符(默认为逗号)可以通过在DomainCollection中设置delimiter属性进行调整。

在视图中显示域名集合

// will output a comma separated list of domain names: google.com, amazon.com
{{ $myModel->domains }}

最后,就像ValueObject一样,ValueObjectCollection也可以用于创建自定义验证器

Validator::extend('domains', function ($attribute, $value, $parameters, $validator) {
    try {
        new DomainCollection($domains);
    } catch (InvalidArgumentException $e) {
        return false;
    }

    return true;
});

验证域名集合

use App\Http\Requests\Request;

class SampleRequest extends Request
{
    ...

    public function rules()
    {
        return ['domains' => 'required|domains'];
    }
}

其他示例

要查看HexColor和HexColorCollection的另一个示例,请查看tests/*目录。