laravel-value-objects
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLaravel Value Objects
Laravel Value Objects
Value objects are simple, immutable objects representing domain concepts.
Related guides:
- DTOs - DTOs are for data transfer, value objects for domain concepts
值对象是代表领域概念的简单、不可变对象。
相关指南:
- DTOs - DTOs用于数据传输,值对象用于领域概念
When to Use
何时使用
Use value objects when:
- Complex domain value with behavior
- Immutability required
- Rich validation logic
- Need equality comparison
- Encapsulating domain rules
Use DTOs when:
- Transferring data between layers
- No domain behavior needed
- See DTOs
在以下场景使用值对象:
- 带有行为的复杂领域值
- 需要不可变性
- 丰富的验证逻辑
- 需要相等性比较
- 封装领域规则
在以下场景使用DTOs:
- 在各层之间传输数据
- 无需领域行为
- 查看 DTOs
Simple Value Object
简单值对象
php
<?php
declare(strict_types=1);
namespace App\Values;
use App\Enums\ProcessResult as ProcessResultEnum;
class ProcessResult
{
public function __construct(
public readonly ProcessResultEnum $result,
public readonly ?string $message = null,
) {}
public static function success(?string $message = null): self
{
return new self(ProcessResultEnum::Success, $message);
}
public static function skip(?string $message = null): self
{
return new self(ProcessResultEnum::Skip, $message);
}
public static function fail(?string $message = null): self
{
return new self(ProcessResultEnum::Fail, $message);
}
public function isSuccess(): bool
{
return $this->result === ProcessResultEnum::Success;
}
public function isFail(): bool
{
return $this->result === ProcessResultEnum::Fail;
}
}php
<?php
declare(strict_types=1);
namespace App\Values;
use App\Enums\ProcessResult as ProcessResultEnum;
class ProcessResult
{
public function __construct(
public readonly ProcessResultEnum $result,
public readonly ?string $message = null,
) {}
public static function success(?string $message = null): self
{
return new self(ProcessResultEnum::Success, $message);
}
public static function skip(?string $message = null): self
{
return new self(ProcessResultEnum::Skip, $message);
}
public static function fail(?string $message = null): self
{
return new self(ProcessResultEnum::Fail, $message);
}
public function isSuccess(): bool
{
return $this->result === ProcessResultEnum::Success;
}
public function isFail(): bool
{
return $this->result === ProcessResultEnum::Fail;
}
}Money Value Object
金额值对象
View full implementation →
查看完整实现 →
Usage Examples
使用示例
ProcessResult
ProcessResult
php
// In actions
return ProcessResult::success('Order processed successfully');
return ProcessResult::skip('Order already processed');
return ProcessResult::fail('Payment declined');
// Checking results
if ($result->isSuccess()) {
// Handle success
}
if ($result->isFail()) {
// Handle failure
}php
// 在动作类中
return ProcessResult::success('订单处理成功');
return ProcessResult::skip('订单已处理');
return ProcessResult::fail('支付被拒绝');
// 检查结果
if ($result->isSuccess()) {
// 处理成功逻辑
}
if ($result->isFail()) {
// 处理失败逻辑
}Money
Money
php
// Creating money values
$price = Money::fromDollars(29.99);
$tax = Money::fromDollars(2.40);
$shipping = Money::fromCents(500); // $5.00
// Operations
$subtotal = $price->add($tax);
$total = $subtotal->add($shipping);
// Multiplication
$bulkPrice = $price->multiply(10);
// Display
echo $total->formatted(); // "37.39"
// Comparison
if ($total->equals($expectedTotal)) {
// Amounts match
}php
// 创建金额值
$price = Money::fromDollars(29.99);
$tax = Money::fromDollars(2.40);
$shipping = Money::fromCents(500); // $5.00
// 运算操作
$subtotal = $price->add($tax);
$total = $subtotal->add($shipping);
// 乘法运算
$bulkPrice = $price->multiply(10);
// 显示
echo $total->formatted(); // "37.39"
// 比较
if ($total->equals($expectedTotal)) {
// 金额匹配
}Key Patterns
核心模式
1. Immutability
1. 不可变性
Use properties:
readonlyphp
public readonly int $amount;
public readonly string $currency;使用属性:
readonlyphp
public readonly int $amount;
public readonly string $currency;2. Static Factory Methods
2. 静态工厂方法
Named constructors for common scenarios:
php
public static function fromDollars(float $dollars): self
public static function success(?string $message = null): self针对常见场景的命名构造函数:
php
public static function fromDollars(float $dollars): self
public static function success(?string $message = null): self3. Private Constructor
3. 私有构造函数
Force use of factory methods:
php
private function __construct(/* ... */) {}强制使用工厂方法:
php
private function __construct(/* ... */) {}4. Domain Logic
4. 领域逻辑
Encapsulate domain rules:
php
public function add(Money $other): self
{
$this->assertSameCurrency($other);
return new self($this->amount + $other->amount, $this->currency);
}封装领域规则:
php
public function add(Money $other): self
{
$this->assertSameCurrency($other);
return new self($this->amount + $other->amount, $this->currency);
}5. Return New Instances
5. 返回新实例
Operations return new instances (immutability):
php
public function add(Money $other): self
{
return new self($this->amount + $other->amount, $this->currency);
}运算操作返回新实例(保证不可变性):
php
public function add(Money $other): self
{
return new self($this->amount + $other->amount, $this->currency);
}Directory Structure
目录结构
app/Values/
├── Money.php
├── ProcessResult.php
├── Coordinate.php
└── EmailAddress.phpapp/Values/
├── Money.php
├── ProcessResult.php
├── Coordinate.php
└── EmailAddress.phpSummary
总结
Value objects:
- Are immutable (use )
readonly - Have static factory methods
- Encapsulate domain logic
- Return new instances from operations
- Validate in constructor
Use for domain concepts with behavior, not simple data transfer.
值对象:
- 是不可变的(使用)
readonly - 具备静态工厂方法
- 封装领域逻辑
- 运算操作返回新实例
- 在构造函数中进行验证
适用于带有行为的领域概念,而非简单的数据传输。