domain-kata
domain-kata copied to clipboard
UsecaseInterfaceの型について
UsecaseInterfaceのrunの引数及びその型について、制約としては厳しく、型としては広すぎるように感じています。
public function run(EntityInterface $entity);
"Usecase"の引数の型がEntityInterfaceである理由には、どのようなものがありますでしょうか。 また後述することについて、Domain Kataが提供する"Usecase"として相応しくない点はありますでしょうか。
現在、Domain Kataを採用している開発チーム内で"Usecase"にはDomain Kataのインターフェースを実装するルールになっており、その結果"Usecase"のrunの一行目では必ずassertionを行っています。
assert($entity instanceof Foo);
個人的には、例としてユーザーを作成する"Usecase"を以下のように書きたいと考えています。
<?php
use AppBundle\Dto\CreateUserDto;
use PHPMentors\DomainKata\Usecase\UsecaseInterface;
class CreateUserUsecase implements UsecaseInterface
{
/**
* @param CreateUserDto $createUserDto
*
* @return User
*/
public function run(CreateUserDto $createUserDto) {
// Create user
}
}
意図としては、以下の通りです。
- "Usecase"を呼び出す際に引数の型を知りたい(IDEにassertionがある場合の型補完機能が備わっていないとして)
- タイトルなどの文字列だけを引数としたい場合に、EntityInterfaceを実装したクラスを作成しないで"Usecase"を作成したい(怠惰な理由ですが、これを行うために"Usecase"の代わりに"Service"で実装するメンバーも多いため)
- 引数のない"Usecase"を作成できるようにしたい
当初 Domain kata は、それが提供する型や派生型の関係を実装プロジェクトにおいて容易に特定し、可視化することを可能にすること、それにより実装プロジェクトのパッケージ構造を自由に設計できるようにすることを意図して作られました。それに加えて、プロジェクトや組織におけるドメインフレームワークの型に対する基盤とすることを意図していました。
UsecaseInterface::run(EntityInterface) は、その一貫として提供されているものですが、引数が EntityInterface であるのは確かに厳しすぎる制約といえます。InOutInterface は、それを補うために提供されており、任意の型を任意の数入出力する要求に応えることができます。とはいえ、引数がないものやプリミティブ型について過剰であることも間違いありません。
解決策として考えられるのは、UsecaseInterface を使用せず、独自にプロジェクトや組織の要求に応えるようなインターフェイスを導入することです。例えば、以下のようなものです。
// ...
interface UsecaseInterface
{
public function run();
}
Domain Kata を改善(UsecaseInterface に変更を加えたり、新たな型を導入)することもできるでしょうが、Domain Kata の制約が使いにくいと思ったなら、その時が独自の型の導入のタイミングといえます。
ご回答ありがとうございます。
ご説明いただいたように、Domain Kataは開発チーム内のプロジェクトにおける型の基盤となっていると思います。
InOutInterfaceを採用した場合も、やはりUsecaseInterface::run(EntityInterface)の引数の制約は避けられないので、
また新規プロジェクトの初期段階などのタイミングで、メンバーと相談しながらDomain Kata-Yaburiに挑戦してみようと思います。