Skip to content

Instantly share code, notes, and snippets.

@rymizuki
Last active September 27, 2019 04:40
Show Gist options
  • Save rymizuki/522e488656f636fe6d41f65769c5520f to your computer and use it in GitHub Desktop.
Save rymizuki/522e488656f636fe6d41f65769c5520f to your computer and use it in GitHub Desktop.
CleanArchitecture + Flux on Console
<?php
namespace Example\Console\Command;
class UserFindCommand extends Symfony\Console\Command\Command
{
private $interactor;
public function __construct(UserFindInteractor $interactor)
{
parent::__construct();
$this->interactor = $interactor;
}
public function configure()
{
// 略
}
public function execute(InputInterface $input, OutputInterface $output)
{
$presenter = $this->interactor->handle(
$input->id
);
$presenter
->onComplete(function ($message) use ($output) {
$output->writeln($message);
})
->onError(function ($error) {
throw $error;
})
;
$this->interactor->start();
}
}
<?php
/**
* 一方向データ通信を行い、ビジネスロジックにControllerからの依存を排除する。
* Consoleなので、一つの処理の中にユーザとの対話が発生することを想定する。
*
* Controller -> Interactor -> Presenter -> Controller
*/
namespace Example\Console\Command;
class UserNameUpdateCommand extends Symfony\Console\Command\Command
{
private $interactor;
public function __construct(UserNameUpdateInteractor $interactor)
{
parent::__construct();
$this->interactor = $interactor;
}
public function configure()
{
// 略
}
public function execute(InputInterface $input, OutputInterface $output)
{
$presenter = $this->interactor->handle(
$input->id,
$input->name,
);
// presenterのイベントを購読する。
$presenter
// ユーザデータが存在していたら、内容を表示して更新の確認を行う
->onFound(function ($message) use ($output) {
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion($message, false);
if (!$helper->ask($input, $output, $question)) {
// キャンセル
$this->interactor->cancel();
return;
}
// 実行
$this->interactor->execute();
})
// キャンセルされたことをユーザに伝えつつ処理を終える
->onCancel(function ($message) use ($output) {
$output->writeln($message);
})
// 処理が完了したら、その結果をユーザに伝える
->onComplete(function ($message) use ($output) {
$output->writeln($message);
})
// エラーが発生したら強制終了
->onError(function ($error) {
throw $error;
})
;
// ユーザとのインタラクションを開始する。
$this->interactor->start();
}
}
<?php
namespace Example\UseCase;
class UseNameUpdateInteractor
{
private $userRepository;
private $id;
private $name;
public function __construct(
UserRepository $userRepository
) {
$this->userRepository = $userRepository;
}
public function handle(int $id, string $name): Presenter
{
$this->id = $id;
$this->name = $name;
}
public function start(): void
{
$user = $this->userRepository->find($id);
if (!$user) {
$this->presenter->emitError(new UserNotFoundException($id));
}
$this->presenter->emitFound();
}
public function cancel(): void
{
$this->presenter->emitCancel();
}
public function execute(): void
{
$this->userRepository->updateName($this->id, $this->name);
$user = $this->userRepository->find($this->id);
if (!$user) {
$this->presenter->emitError(new ArienaiException($id));
}
$this->presenter->emitComplete($user);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment