###### 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; } } ```