Laravelのサービスコンテナを上手に利用する方法

LaravelではMVCモデルというアーキテクチャが採用されています。

MVCモデルとはざっくりいうと

  • 画面を表示させるHTMLに近しいビュー(View)
  • 条件分岐をしながら指令を渡すコントローラー(Controller)
  • 計算ロジックやリレーションを定義するモデル(Model)

の3つを軸とした構成のことです。

しかしコントローラーで条件分岐を書き過ぎている、もしくは複雑なロジックを含めて書いているとコードが長くなり可読性が劣ります。

長いコードではのちの修正にも時間がかかりますし、
他の人からみたらさらに読みにくく効率が下がるでしょう。

また、小規模の開発であったとしても、「同じ処理を複数の場面で使用したい」ケースもあります。

上記の画面のように、クリック時に表示内容が変更されても、
ヘッダー付近のグラフなどはそのままにしておきたい場合もあるでしょう。

その場合、グラフの計算処理を再びコーディングするよりかは、クラス化して使う方が楽です。

そのクラスを別のファイルに書いて責務分担することが本記事の目的です。

Laravelのサービスコンテナの内容

サービスコンテナの内容

まずは/Appフォルダに新しくServiceというフォルダを作成してください。

<?php

namespace App\Services;
use App\Models\Task;

class UserTaskProcessing
{
    public function getTotalEstimatedTime($userId)
    {
        return Task::where('responsible_user_id', $userId)->sum('estimated_time');
    }

    public function getTotalRealTime($userId)
    {
        return Task::where('responsible_user_id', $userId)->sum('real_time');
    }

}

タスク管理アプリにて、ヘッダー付近に

  • ログインしてるユーザーのタスク処理予想時間の合計
  • ログインしてるユーザーのタスク処理実績時間の合計

を載せたいときのクエリビルダをこちらに記入します。

コントローラーの内容

class TallyDataController extends Controller
{
    public function index() {...}

    public function update() {...}
 
    public function view() {...}
}

上記のような大枠の処理が書かれてあるとします。

class TallyDataController extends Controller
{
    public function index()
  {
      $process = new UserTaskProcessing();
       ......
  }

    public function update() 
  {
      $process = new UserTaskProcessing();
        ........
  }

    public function view()
  {
      $process = new UserTaskProcessing();
       .......
  }

}

このように各関数の中で何度も新たにクラスを生成しているのは非効率的です。

class TallyDataController extends Controller
{
   // ここでDI(依存性注入)を利用する
  private UserTaskProcessing $calculation;
  public function __construct(UserTaskProcessing $process)
  {
       $this->process = $process;
  }

    public function index()
  {
     $this->process->getTotalEstimatedTime(1)
  }

    public function update($userId) 
  {
       $this->process->getTotalEstimatedTime($userId)
  }

    public function view()
  {
       $this->process->...
  }

}

DI(依存性注入)を使用することにより、クラス生成の処理が1回で済むのがメリットです。

タイトルとURLをコピーしました