waavi / laravel-value-objects
Laravel 5.1 的值对象
Requires
- illuminate/cache: 5.1.x
- illuminate/http: 5.1.x
- illuminate/support: 5.1.x
Requires (Dev)
- mockery/mockery: ^0.9.4
- orchestra/testbench: 3.1.x
- phpunit/phpunit: ^4
This package is auto-updated.
Last update: 2024-09-13 23:28:08 UTC
README
允许你在 Eloquent 模型中创建值对象,然后将其作为普通字符串或 json 编码保存到数据库中。
WAAVI 是一家位于西班牙马德里的网络开发工作室。您可以在 waavi.com 上了解更多关于我们的信息。
安装
您可以通过 composer 安装此包
composer require waavi/laravel-value-objects 1.0.x
用法
使用单字段值对象
假设您想向 Device Eloquent 模型添加一个 Temperature 字段。您可能希望对此字段应用转换,或以摄氏度、华氏度或开尔文为单位获取值。如果您在多个模型中使用此类字段,则可能需要在所有模型之间复制粘贴这些函数,这可能变得很麻烦。
这就是值对象变得非常有用的地方。让我们看看它是如何工作的。首先,我们创建了 Device 模型,该模型将具有一个转换为 Temperature 值对象的温度字段,并使用 'CastsValueObjects' 特性。
use Illuminate\Database\Eloquent\Model; class Device extends Model { use \Waavi\ValueObjects\Traits\CastsValueObjects; /** * The attributes that should be casted to native types. * * @var array */ protected $casts = [ 'temperature' => Temperature::class, ]; }
Temperature 值对象将扩展自 'Waavi\ValueObjects\Single',可以定义如下
use Waavi\ValueObjects\Single; class Temperature extends Single { /** * @return float */ public function inCelsius() { // In single field value objects, the name of the field is always $value return (float) $this->value; } /** * @return float */ public function inKelvin() { return (float) $this->value + 273.15; } /** * @return float */ public function inFahrenheit() { return (float) $this->value * 1.8 + 32; } }
单字段值对象以普通字符串形式保存到数据库中,可以使用以下方式使用
$device = new Device; $device->temperature = new Temperature(30); $device->temperature = 30; // This also works echo $device->temperature; // Prints '30' echo $device->temperature->value; // Prints '30' echo $device->temperature->inKelvin(); // Prints 303.15
您也可以使用访问器和修改器,就像在 Eloquent 模型中一样。例如,您可以重新编写 Temperature 类如下
use Waavi\ValueObjects\Single; class Temperature extends Single { /** * Make all subzero temperatures equal to zero. * @return void */ public function setValueAttribute($value) { $this->attributes['value'] = $value > 0 ? $value : 0; } /** * @return float */ public function getCelsiusAttribute() { return (float) $this->value; } /** * @return float */ public function getKelvinAttribute() { return (float) $this->value + 273.15; } /** * @return float */ public function getFahrenheitAttribute() { return (float) $this->value * 1.8 + 32; } }
然后,您可以按如下方式访问温度属性
$device = new Device; $device->temperature = 30; echo $device->temperature; // Prints '30' echo $device->temperature->value; // Prints '30' echo $device->temperature->kelvin; // Prints 303.15
使用多字段值对象
有时值对象可能不是那么简单,可能需要多个字段而不是一个字段。假设我们有一个包含起点和终点字段的 Trip 模型,这些字段由坐标组成。然后,我们可以像以前一样定义 Trip 模型
use Illuminate\Database\Eloquent\Model; class Trip extends Model { use \Waavi\ValueObjects\Traits\CastsValueObjects; /** * The attributes that should be casted to native types. * * @var array */ protected $casts = [ 'origin' => Coordinate::class, 'destination' => Coordinate::class, ]; }
然后,我们可以定义 Coordinate 值对象如下
use Waavi\ValueObjects\Json; class Coordinate extends Json { protected $fillable = ['lat', 'lng']; /** * Return the distance between this coordinate and another * * @return float */ public function distanceTo(Coordinate $coord) { /** Calculate distance **/ return $distance; } }
现在我们需要扩展自 'Waavi\ValueObjects\Json' 值对象,因为我们需要多个字段来表示我们的值对象,并且我们需要定义一个包含允许在值对象中使用的字段名称的 fillable 数组。这次,字段在保存之前将被 json 编码。
与之前一样,提供了修改器和访问器。
我们可以这样处理这个模型对象
$trip = new Trip; $trip->origin = new Coordinate(['lat' => 20.1221, 'lng' => 12.1231]); $trip->destination = new Coordinate(['lat' => 10.13, 'lng' => 12.14]); echo $trip->origin; // Prints json representation {'lat':'20.1221','lng':'12.1231'} echo $trip->origin->lat; // Prints '20.1221' echo $trip->origin->distanceTo($trip->destination); // Prints distance between them.