该软件包已被废弃,不再维护。未建议替代软件包。

面向结果的对象和上下文

v3.0.0 2020-02-09 21:11 UTC

This package is auto-updated.

Last update: 2022-07-10 02:35:47 UTC


README

logo

Result库的目标是在请求存储或任何可以返回“无”或所需结果的任何对象时,告别iftry catch控制结构。

代码也变得更加声明性和面向对象。

示例

使用存储库

上下文:我们只想向一个用户发送消息,该用户仅以其ID为已知。

通常情况下的做法

<?php

// ---------------------------------------- interfaces

interface User
{
    public function sendMessage(string $text): void;
}

interface UserRepository
{
    public function userById(int $uuid): User|null;
}

// ---------------------------------------- implementation

$userRepository = new MySqlUserRepository();

$user = $userRepository->userById(1234);

if (true === is_null($user)) {
    // error handling
} else {
    $user->sendMessage('Hi!');
}

使用Result

<?php

// ---------------------------------------- interfaces

interface User
{
    public function sendMessage(string $text): void;
}

interface UserRepository
{
    public function userById(int $uuid): Result<User>;
}

// ---------------------------------------- implementation

$userRepository = new MySqlUserRepository();

$userRepository
    ->userById(1234)
    ->then(function (User $user) {
        $user->sendMessage('Hi!');
    })
    ->else(function (Error $error) {
        // error handling
    });

在HTTP控制器内

上下文:我们想获取一个用户名,并在用户已知时通过HTTP#200响应返回它,在用户未知时通过HTTP#404返回。

通常情况下的做法

<?php

// ---------------------------------------- interfaces

interface User
{
    public function name(): string;
}

interface UserRepository
{
    public function userById(int $uuid): User|null;
}

// ---------------------------------------- implementation

class UserNameController
{
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function handle(int $uuid): Response {
        $user = $this->userRepository->userById($uuid);

        if (true === is_null($user)) {
            $response = new Response(
                sprintf('the user %s does not exist', $uuid),
                404
            );
        } else {
            $response = new Response($user->name(), 200);
        }

        return $response;
    }
}

使用Result

<?php

// ---------------------------------------- interfaces

interface User
{
    public function name(): string;
}

interface UserRepository
{
    public function userById(int $uuid): Result<User>;
}

// ---------------------------------------- implementation

class UserNameController
{
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function handle(int $uuid): Response {
        return $this->userRepository
            ->userById($uuid)
            ->map(function (User $user) {
                return new Response($user->name(), 200);
            })
            ->getOr(function (Error $error) use ($uuid) {
                return new Response(
                    sprintf('the user %s does not exist', $uuid),
                    404
                );
            });
    }
}

如何管理多个不确定性?

上下文:我们想将一个用户添加到组中。但只提供了相应的ID。两者可能都不存在。

通常情况下的做法

<?php

// ---------------------------------------- interfaces

interface User
{
    public function name(): string;
}

interface Group
{
    public function add(User $user): void;
}

interface UserRepository
{
    public function userById(int $uuid): User|null;
}

interface GroupRepository
{
    public function groupById(int $uuid): Group|null;
}

// ---------------------------------------- implementation

$group = $this->groupRepository->groupById($groupUuid);
$user  = $this->userRepository->userById($userUuid);

if (true === is_null($user) || true === is_null($user)) {
    // error handling
} else {
    $group->add($user);
}

使用Result

<?php

// ---------------------------------------- interfaces

interface User
{
    public function name(): string;
}

interface Group
{
    public function add(User $user): void;
}

interface UserRepository
{
    public function userById(int $uuid): Result<User>;
}

interface GroupRepository
{
    public function groupById(int $uuid): Result<Group>;
}

// ---------------------------------------- implementation

(new Combined([
    $this->groupRepository->groupById($groupUuid),
    $this->userRepository->userById($userUuid),
]))
    ->then(function (Group $group, User $user) {
        $group->add($user);
    })
    ->else(function (Error $error) {
        /** error handling */
    });

或者

<?php

// ---------------------------------------- implementation

$this->groupRepository
    ->groupById($groupUuid)
    ->join($this->userRepository->userById($userUuid))
    ->then(function (Group $group, User $user) {
        $group->add($user);
    })
    ->else(function (Error $error) {
        /** error handling */
    });