Skip to content

Instantly share code, notes, and snippets.

@izayoi256
Last active November 9, 2020 07:45
Show Gist options
  • Save izayoi256/f70f860a8dbe29ceb0b2a1af2643b12f to your computer and use it in GitHub Desktop.
Save izayoi256/f70f860a8dbe29ceb0b2a1af2643b12f to your computer and use it in GitHub Desktop.
[EC-CUBE4] シングルアクションコントローラー

シングルアクションコントローラーとは

1コントローラーに1アクションのみを記述したコントローラー。 責務の切り分けに役立つ。

責務とは

そのクラスが成すことを期待される機能。 publicメソッドは外部から使用される可能性がある、つまり責務を表すもの。 逆にprotectedメソッドやprivateメソッドは外部から使用される可能性はない。

そのクラスの責務ではないメソッドはprotectedやprivateで隠蔽しよう。

どうやって責務を切り分ける?

例えばSomethingを扱うSomethingControllerがあり、その中には Somethingを検索するsearchSomething()メソッドと Somethingを作成するcreateSomething()メソッドがあるとする。

searchSomething()に関するコードを修正した場合、 同じクラス内に含まれるcreateSomething()にも影響が及ぶ可能性は否定できない。

これらをSearchSomethingActionとCreateSomethingActionという別々のクラスとして定義することで、 Somethingの検索に関するコードはSearchSomethingActionクラスだけを見ればよく、 Somethingの作成に関するコードはCreateSomethingActionクラスだけを見ればいい という状態を目指す。

1つのクラスに1つの責務を持たせるのは、SOLID原則のS(単一責任の原則)にあたる。

<?php
namespace Customize\Controller;
use Customize\Entity\Something;
use Eccube\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
/**
* このクラスの責務は「Somethingを作ること」
*/
final class CreateSomethingAction extends AbstractController
{
/**
* Somethingを作成するアクションにはSomethingRepositoryは不要ですよね。
* 必要なところに必要な依存性だけを注入しましょう。
*/
// public function __construct()
// {
// }
/**
* @Route("/something", name="something_create", methods={"POST"})
*/
public function __invoke()
{
$this->createSomething();
}
/**
* 公開する必要のないメソッドはprivateやprotectedとして、
* このクラスの責務に含まれないことを明確にする。
*/
private function createSomething(): void
{
$Something = new Something();
$this->entityManager->persist($Something);
$this->entityManager->flush();
}
}
<?php
namespace Customize\Controller;
use Customize\Repository\SomethingRepository;
use Doctrine\Common\Collections\Collection;
use Eccube\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
/**
* このクラスの責務は「Somethingを検索すること」
*/
final class SearchSomethingAction extends AbstractController
{
/** @var SomethingRepository */
private $somethingRepository;
/**
* Somethingを検索するアクションにはSomethingRepositoryが必要ですよね。
*/
public function __construct(SomethingRepository $somethingRepository)
{
$this->somethingRepository = $somethingRepository;
}
/**
* @Route("/something", name="something_search", methods={"GET"})
*/
public function __invoke()
{
$Somethings = $this->searchSomething();
}
/**
* 公開する必要のないメソッドはprivateやprotectedとして、
* このクラスの責務に含まれないことを明確にする。
*/
private function searchSomething(): Collection
{
return $this->somethingRepository->search();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment