PHP
どう書く
設計
SOLID

SOLIDの原則ってどんなふうに使うの?に登場するTODOアプリを実装してみた

SOLIDの原則ってどんなふうに使うの?に登場する「先輩」によるコード修正が入る前で一旦読むことをやめ、自分なりにコードを書いてみました。

以下書きなぐったコードです(雰囲気だけ掴んでもらえると嬉しいです)

todo.php
class App
{
    public function show()
    {
        $allTodo = $this->todoRepository->findAll();
        foreach ($allTodo as $todo) {
            $todo->display();
        }
    }
}

Interface Displayable
{
    public function display();
}

abstract class Todo
{
    public function display()
    {
        echo '--';
        echo $this->getTitle();
        echo $this->getUrl();
    }

    abstract protected function formatStatus();

    abstract protected function formatTitle($statusLabel);

    private function getTitle()
    {
        $statusLabel = $this->formatStatus();
        return $this->formatTitle($statusLabel);

    }
}

class NormalTodo extends Todo implements Displayable
{
    protected function formatStatus()
    {
        $status = $this->getStatus();
        $map = [
            'pending' => '[未着手]',
            'running' => '[作業中]',
            'completed' => '[完了]'
        ];
        return $map[$status];
    }

    protected function formatTitle($statusLabel)
    {
        return sprintf('%s%s', $statusLabel, $this->getTitle());
    }

    protected function getUrl()
    {
        //urlを取得する処理
    }

    private function getStatus()
    {
        //statusを取得する処理
    }

    private function getTitle()
    {
        //titleを取得する処理
    }
}

class GoogleCalenderTodo extends Todo implements Displayable
{
    protected function formatStatus()
    {
        $date = $this->getEndDateTime();
        //googleCalender用のstatusを取得する処理
    }

    protected function formatTitle($statusLabel)
    {
        $title = sprintf('%s%s', $statusLabel, $this->getTitle());
        $title =. sprintf('($s)', $this->getLocation()); //メソッドに切り出す
        return $title;
    }

    protected function getUrl()
    {
        //urlを取得する処理
    }

    private function getTitle()
    {
        //titleを取得する処理
    }

    private function getEndDateTime()
    {
        //完了日時を取得する処理
    }

    private function getLocation()
    {
        //ロケーションを取得する処理
    }
}

という感じになりました。

反省点としては、クラスの責務をしっかり考えられなかったことが挙げられます。
「先輩」は表示処理の責務をPresenterクラスに移譲していたのに対し、私は表示処理の責務をTodoクラスに押し込みました。

自分の良くないところが認識できたので、とても良い経験になりました。
後藤さん素晴らしいスライドをありがとうございました。