オブジェクト指向を使っていて、ひとついいなと思ったことです。
リファクタリング 既存のコードを安全に改善する(第2版)という書籍では、「オブジェクトによるプリミティブの置き換え」と命名されていました。
todo アプリを例に説明します。
int
での引き渡し
int
で引き渡していると、各コンポーネントは「$task_id
<= 0 のときに次に渡すとバグるかもしれないな...」ということを考える必要が生じます。
TaskId
オブジェクトでの引き渡し
TaskId
オブジェクトを作成して受け渡すことで、0以下だった場合の心配をする必要がなくなります。
コード
int
で受け渡したとき
class TaskDeleteController
{
public function respond($task_id): void
{
if ($task_id <= 0) {
throw new RuntimeException();
}
$this->service->delete($task_id);
...
}
class TaskDeleteService
{
public function delete(int $task_id): void
{
if ($task_id <= 0) {
throw new RuntimeException();
}
$this->repository->delete($task_id);
...
}
class TaskRepository
{
public function delete(int $task_id): void
{
if ($task_id <= 0) {
throw new RuntimeException();
}
$query = <<<'SQL'
delete from tasks
...
}
TaskId
オブジェクトで受け渡したとき
class TaskId
{
public function __construct(int $task_id)
{
if ($task_id <= 0) {
throw new TaskIdValidateException();
}
...
}
class TaskDeleteController
{
public function respond(int $task_id): void
{
try {
$task_id = new TaskId($task_id);
} catch (TaskIdValidateException) {
throw new RuntimeException();
}
$this->service->delete($task_id);
...
}
class TaskDeleteService
{
public function delete(TaskId $task_id): void
{
$this->repository->delete($task_id);
...
}
class TaskRepository
{
public function delete(TaskId $task_id): void
{
$query = <<<'SQL'
delete from tasks
...
}