---
# System prepended metadata

title: Controller 的問題跟後續解法
tags: [架構, laravel]

---

###### tags: `架構` `laravel`

# Controller 的問題跟後續解法

+ 原始情況

    + 缺點
        1. controller 過於肥大
        2. 擴充功能不易

```php
class cyclingController
{
    //取得統計資料
    public index()
    {
        $users = $userModel->where($conditions)->get($fields);
        foreach ($users as $user) {
            //$usersResult = 複雜計算處理結果...

            $statistics = array_merge(statistics, $usersResult);
        }

        $cyclingData = $cyclingModel->where($conditions)->get($fields);
        foreach ($cyclingData as $cycling) {
            //$cyclingDataResult = 複雜計算處理結果...

            $statistics = array_merge(statistics, $cyclingDataResult);
        }

        $bikes = $bikeModel->where($conditions)->get($fields);
        foreach ($bikes as $bike) {
            //$bikesResult = 複雜計算處理結果...

            $statistics = array_merge(statistics, $bikesResult);
        }

        return $statistics;
    }
}
```


---


+ 第二版

    + 缺點
        1. controller 過於肥大
        2. 擴充功能不易
        3. 注入問題
    + 優點
        1. 易讀

```php
class cyclingController
{
    private $userRepository;
    private $cyclingRepository;
    private $bikeRepository;
    private $userService;
    private $cyclingService;
    private $bikeService;

    public function __construct(
        UserRepository    $userRepository,
        CyclingRepository $cyclingRepository,
        BikeRepository    $bikeRepository,
        UserService       $userService,
        CyclingService    $cyclingService,
        BikeService       $bikeService
    ) {
        $this->userRepository    = $userRepository;
        $this->cyclingRepository = $cyclingRepository;
        $this->bikeRepository    = $bikeRepository;
        $this->userService       = $userService;
        $this->cyclingService    = $cyclingService;
        $this->bikeService       = $bikeService;
    }

    //取得統計資料
    public index()
    {
        $statistics = [];

        $users = $this->userRepository->takeAll($conditions, $fields);
        $statistics = array_merge($statistics, $this->userService->calculation($users));

        $cyclingData = $this->cyclingRepository->takeAll($conditions, $fields);
        $statistics = array_merge($statistics, $this->cyclingService->calculation($cyclingData));

        $bikes = $this->bikeRepository->takeAll($conditions, $fields);
        $statistics = array_merge($statistics, $this->bikeService->calculation($bikes));

        return $statistics;
    }
}

class UserRepository
{
    public function takeAll(array $conditions, array $fields)
    {
        return $userModel->where($conditions)->get($fields);
    }
}

class UserService
{
    public function calculation(array $users)
    {
        foreach ($users as $user) {
            //$usersResult = 複雜計算處理結果...
            
            $statistics = array_merge(statistics, $usersResult);
        }

        return $statistics;
    }
}
```


---


+ 第三版

    + 缺點
        1. 目錄可能太多
    + 優點
        1. controller不用負責太多

```php
class StatisticsController
{
    //取得統計資料
    public function index()
    {
        foreach (['user', 'cycling', 'bike'] as $type) {
            $statistics[] = CyclingStatisticsFactory::generate($type)->calculation($conditions, $fields);
        }

        return $statistics;
    }
}

interface StatisticsInterface
{
    public function calculation(array $conditions, array $fields);
}

class StatisticsFactory
{
    public static function generate($type)
    {
        switch ($type) {
            case 'user':
                return New UserStatistics();
            case 'cycling':
                return New CyclingStatistics();
            case 'bike':
                return New BikeStatistics();
        }
    }
}

class UserStatistics implements StatisticsInterface
{

    public function calculation()
    {
        $users = $userModel->where($conditions)->get($fields);
        $statistics = [];
        foreach ($users as $user) {
            //$statistics = 複雜計算處理結果...
        }

        return $statistics;
    }
}
```
