DEV Community

imunew
imunew

Posted on

The Easiest Way to Implement ValueObjects in Laravel

First.

You don't need to find a way to implement ValueObjects.
You should only make a "app/ValueObjects" directory.

But, I released the package "imunew/laravel-value-objects" that you can generate files automatically by the "php artisan make:value-object" command.

The source code is here.

You can install it with "composer require imunew/laravel-value-objects".

I want a ValueObject like this

The following is what we are looking for in a ValueObject.

  • immutable
    • Only set data only with the __construct
    • Don't make the setter public
    • @property-readable properties can be accessed
  • Like the Eloquent Model
    • No need to write getter per properties
    • Can implement Accessor (get{Attribute}Attribute)
    • You can create a file with the command "php artisan make:value-object".

I tried to find a package on packagist, but there was none that met my requirements.

The chalcedonyt/laravel-valueobject is immutable, and has a make command, which is nice, but, unfortunately, it stopped being updated after 2015-11-13 and was not compatible with Laravel 6.x or later.

It works like this.

Example 1) Range class.

namespace App\ValueObjects;

use Imunew\Laravel\ValueObjects\ImmutableObject;

class Range extends ImmutableObject
{
    /**
     * Range constructor.
     * @param int $start
     * @param int $end
     * @param int $step
     */
    public function __construct(int $start, int $end, int $step = 1)
    {
        $this->setAttribute('start', $start);
        $this->setAttribute('end', $end);
        $this->setAttribute('step', $step);
    }

    /**
     * @return array
     */
    public function getRangeAttribute()
    {
        return range($this->start, $this->end, $this->step);
    }
}
Enter fullscreen mode Exit fullscreen mode
$range = new Range(1, 10);
echo $range;
// [1,2,3,4,5,6,7,8,9,10]
Enter fullscreen mode Exit fullscreen mode

Example 2) DirectoryTree class

namespace App\ValueObjects;

use Imunew\Laravel\ValueObjects\ImmutableObject;

class DirectoryTree extends ImmutableObject
{
    /**
     * Range constructor.
     * @param array $directoryTree
     */
    public function __construct(array $directoryTree)
    {
        $this->attributes = $directoryTree;
    }
}
Enter fullscreen mode Exit fullscreen mode
$directoryTree = new DirectoryTree([
    'app' => [
        'Http' => [
            'Controllers' => [],
            'Middleware' => [],
            'Requests' => [],
            'Resources' => [],
        ],
        'ValueObjects' => []
    ]
]);

echo json_encode($directoryTree->get('app.Http'));
// {"Controllers":[],"Middleware":[],"Requests":[],"Resources":[]}
Enter fullscreen mode Exit fullscreen mode

Conclusion.

I think I've created a nice Laravel package.
Please try to use it.

Bye.

Top comments (0)