Back to list
leeovery

laravel-value-objects

by leeovery

Opinionated Laravel Skills & Commands for Claude Code

10🍴 2📅 Jan 20, 2026

SKILL.md


name: laravel-value-objects description: Immutable value objects for domain values. Use when working with domain values, immutable objects, or when user mentions value objects, immutable values, domain values, money objects, coordinate 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

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

Simple Value Object

<?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

// 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
}

Money

// 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
}

Key Patterns

1. Immutability

Use readonly properties:

public readonly int $amount;
public readonly string $currency;

2. Static Factory Methods

Named constructors for common scenarios:

public static function fromDollars(float $dollars): self
public static function success(?string $message = null): self

3. Private Constructor

Force use of factory methods:

private function __construct(/* ... */) {}

4. Domain Logic

Encapsulate domain rules:

public function add(Money $other): self
{
    $this->assertSameCurrency($other);
    return new self($this->amount + $other->amount, $this->currency);
}

5. Return New Instances

Operations return new instances (immutability):

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.php

Summary

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.

Score

Total Score

60/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon