monsieurluge / result
该软件包已被废弃,不再维护。未建议替代软件包。
面向结果的对象和上下文
v3.0.0
2020-02-09 21:11 UTC
Requires
- php: ^7.2
Requires (Dev)
- phpmd/phpmd: @stable
- phpstan/phpstan: ^0.12.7
- phpunit/phpunit: *
README
Result库的目标是在请求存储或任何可以返回“无”或所需结果的任何对象时,告别if
和try 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 */ });