Service 放的是商業邏輯。
基本上Service跟前兩章提到的Entity還有Repository 在laravel沒有特別提到,但是為什麼還要這樣拆呢?
這是因為如果都放在一起,甚至是直接放在Controller的話,會造成檔案過於肥大,在寫測試的時候也很難隔離,日後會很難維護,尤其是在共同開發的狀態下。
<?php
namespace App\Services;
use App\Repositories\ProductRepository;
class ProductService
{
protected $productedRepository;
public function __construct()
{
$this->productRepository = new ProductRepository();
}
public function get()
{
$products = $this->productRepository->get();
$data = []; //養成良好的習慣先宣告比較不容易踩雷
foreach ($products as $product) {
$data[] = [
'id' => $product->id,
'product_name' => $product->name,
];
}
return $data;
}
前一章有提到如果用query builder宣告的話,在使用上會比較彈性,底下是範例。
public function getName($json)
{
//如果有更多條件的話,可以選擇需要的情境過濾
if (null !== $json->name) {
$this->productRepository->filterByName($json->name);
}
return $this->productRepository->get();
}
另外有一點提一下,或許有些人在剛開始的時候會把Service 跟 Service Provider搞混,但是其實這兩個是不同的東西
Service 是我們自己定義抽離出商業邏輯的部分
Service Provider 服務提供者是所有 Laravel 應用程式的啟動中心,我們的應用程式,以及所有 Laravel 的核心服務,都是透過服務提供者啟動。
注入的方式先不提到,因為他比較複雜,有興趣的話可以參考 在 Laravel 4 使用資源庫 (Repositories) 及服務 (Services) 去降低程式的耦合性
結論: 覺得如果在應用上面的code真的比較多的話,應該要拆出來service,讓Controller能夠專心做Request和傳遞的接口,這樣也可以符合 SOLID 的單一職責原則。
參考連結:
1:if (null !== $json->name)
2: {
3: $this->productRepository->filterByName($json->name);
4: }
5: return $this->productRepository->get();
為什麼可以這樣由3進去Repository先查,查完後,再由5進去Repository get?
謝謝你的提問!
這邊補充一下,此段是根據前一篇Repository內query builder的範例,取得query builder以後在Service的用法。