Preskočiť na obsah

Ponorte sa do návrhových vzorov „Laravel“: vzor Action, vzor Repository a Query Service

Ponorte sa do návrhových vzorov „Laravel“: vzor Action, vzor Repository a Query Service

Prečo sú dôležité návrhové vzory

Ak ste pracovali s Laravelom, viete, že je to fantastický framework, ktorý vám pomáha rýchlo vytvárať aplikácie. Ale ako váš projekt rastie, veci sa môžu začať komplikovať. Kontroléry môžu narásť do obrovských rozmerov, dotazy sú roztrúsené všade a testovanie vášho kódu sa môže zdať nemožné. Tu prichádzajú na pomoc návrhové vzory. Poskytujú vám lepšie spôsoby, ako organizovať kód, aby zostal prehľadný a ľahko spravovateľný.

V tomto článku sa pozrieme na tri užitočné návrhové vzory v Laraveli: vzor akcie, vzor úložiska a služba dotazov. Každý z nich má svoje klady a zápory a je dôležité vedieť, kedy ich použiť. Ako hovorí Povilas Korop: „Akékoľvek použitie vzorov ZÁVISÍ od tímu, projektu a vývojára.“ Pre môj súčasný veľký projekt sme zvolili vzor akcie a službu dotazov, ale v minulosti som používal aj vzor úložiska.

Rýchly prehľad nastavenia môjho súčasného projektu

Pre náš najnovší projekt Dental software sme sa rozhodli pre vzor akcie, aby sme zefektívnili našu obchodnú logiku, a vzor služby dotazov, aby sme zvládli zložité dotazy. V predchádzajúcich projektoch sme používali vzor úložiska, ale v tomto prípade to jednoducho nedávalo zmysel. Pozrime sa, prečo.

Vzor akcie

Vzor akcie sa zameriava na organizáciu kódu tak, aby bol ľahšie zrozumiteľný a udržiavateľný. Namiesto toho, aby ste vložili množstvo logiky do svojich kontrolérov alebo tried služieb, vytvoríte malé triedy nazývané akcie. Každá akcia vykonáva len jednu vec, čo zjednodušuje testovanie a opätovné použitie vášho kódu.

Predstavte si napríklad, že potrebujete vytvoriť objednávku, poslať e-maily zákazníkovi a správcovi a zaznamenať, že objednávka bola vytvorená. Namiesto toho, aby ste to všetko vtesnali do svojho kontroléra, môžete použiť triedu akcie, ako je táto:

class CreateOrderAction
{
public function execute(CreateOrderDto $data): Order
{
// Vytvorte objednávku
$order = new Order();
$order->user_id = $data->user_id;
$order->total_amount = $data->total_amount;
$order->status = OrderStatusEnum::PENDING;
$order->save();

// Spracovanie udalostí ďalšie kroky, ako sú oznámenia, ktoré sa posielajú asynchrónne
OrderCreated::dispatch($order);

return $order;
}
}

Potom v kontroléri stačí zavolať túto akciu:

public function store(CreateOrderRequest $request, CreateOrderAction $action)
{
$order = $action->execute($request->getCreateOrderDto());

return response()->json([‚message‘ => ‚Objednávka bola úspešne vytvorená!‘, ‚order‘ => $order]);
}

Vybrali sme tento vzor, pretože udržuje naše kontroléry jednoduché, čím sa ľahšie spravujú. Navyše, testovanie je jednoduché, pretože každá akcia je samostatnou triedou. Nevýhoda? Ak je váš projekt malý, vytváranie samostatnej triedy pre všetko sa môže zdať ako príliš veľa. Ak máte príliš veľa akcií, ich organizovanie môže byť náročné.

Vzor repozitára

Vzor repozitára vytvára vrstvu medzi vašimi kontrolérmi a modelmi, čím je váš kód flexibilnejší. Namiesto priamej práce s modelmi Eloquent používate repozitár na spracovanie prístupu k dátam. Vďaka tomu je váš kód prehľadný a neskôr je jednoduchšie zmeniť spôsob ukladania dát.

Tu je základný UserRepository:

use App\Models\User;

class UserRepository
{
public function findById(int $id): ?User
{
return User::find($id);
}

public function findByEmail(string $email): ?User
{
return User::where(‚email‘, $email)->first();
}

public function create(array $data): User
{
return User::create($data);
}

public function update(int $id, array $data): bool
{
$user = $this->findById($id);
return $user ? $user->update($data) : false;
}
}

V kontroléri môžete použiť tento repozitár na udržanie poriadku:

public function show(int $id, UserRepository $userRepository)
{
$user = $userRepository->findById($id);
return response()->json($user);
}

public function update(UpdateUserRequest $request, int $id, UserRepository $userRepository)
{
$success = $userRepository->update($id, $request->getUpdateUserDto());
return response()->json([‚success‘ => $success]);
}

V našom súčasnom projekte sme sa rozhodli nepoužívať vzor repozitára. Naše požiadavky na dáta boli jednoduché a priame použitie Eloquent bolo dostatočné. Pridanie vrstvy repozitára by veci skomplikovalo. Tento vzor je však skvelý, ak máte komplexné alebo meniace sa zdroje dát a potrebujete väčšiu flexibilitu.

Služba Query

Služba Query je ideálna na spracovanie komplexného načítania údajov. Zameriava sa na operácie len na čítanie a pomáha vám udržiavať vaše modely a radiče čisté. Ak máte veľa zložitých dotazov, tento vzor môže uľahčiť údržbu vášho kódu.

Predpokladajme napríklad, že potrebujete načítať používateľov s rôznymi filtrami a možnosťami triedenia. Môžete použiť UserQueryService: \

use App\Models\User;

class UserQueryService
{
public static function model(): Builder|CompanyModel
{
return User::query();
}

public static function getActiveUsers(int $limit = 10)
{
return self::model()->where(‚active‘, true)->limit($limit)->get();
}

public static function getUsersByRole(string $role)
{
return self::model()->where(‚role‘, $role)->get();
}

public static function searchUsers(string $query, int $perPage = 15)
{
return self::model()->(‚name‘, ‚like‘, ‚%‘ . $query . ‚%‘)
->orWhere(‚email‘, ‚like‘, ‚%‘ . $query . ‚%‘)
->paginate($perPage);
}
}

Túto službu môžete vo svojom ovládači použiť takto:

public function index(SearchUserRequest $request, UserQueryService $userQueryService)
{
$dto = $request->getSearchDto();
$users = $userQueryService::searchUsers($dto->query);

return view(‚users.index‘, compact(‚users‘));
}

Pre náš projekt mal tento vzor dokonalý zmysel. Udržal naše modely zamerané a našu logiku dotazov organizovanú. Uľahčil tiež optimalizáciu výkonu, pretože všetky naše dotazy boli na jednom mieste. Nevýhodou je, že slúži len na čítanie údajov, takže na zapisovanie alebo aktualizáciu údajov budete potrebovať iné riešenia.

Zhrnutie

Výber správnych návrhových vzorov nie je len o dodržiavaní osvedčených postupov, ale aj o uľahčení života vývojára. Zamyslite sa nad problémami, ktoré sa snažíte riešiť, a nad tým, ako každý vzor môže zjednodušiť váš kód.

Vzor akcie je revolučný, ak chcete, aby vaša obchodná logika bola organizovaná a opakovane použiteľná. Ak ste sa niekedy cítili zahltení objemnými kontrolérmi alebo ťažko testovateľným kódom, akcie sú vaším novým najlepším priateľom. Predstavte si, že máte malé, zamerané triedy, ktoré spracovávajú jednotlivé úlohy a vďaka nim je váš projekt opäť zvládnuteľný.

Pokiaľ ide o načítavanie údajov, služba dotazov je ako podvádzací list pre zložité dotazy. Namiesto toho, aby ste zapĺňali svoje modely alebo kopírovali logiku dotazov všade, máte jedno miesto, kde môžete spravovať všetky svoje potreby v oblasti získavania údajov. Vďaka tomu sú veci prehľadné, optimalizované a ľahko udržiavateľné.

Na druhej strane, ak máte pocit, že váš projekt potrebuje flexibilný spôsob spracovania prístupu k údajom, stojí za zváženie vzor repozitára. Aj keď to pre náš súčasný projekt nedávalo zmysel, v minulosti sa ukázalo ako cenné, najmä pri spracovaní meniacich sa zdrojov údajov alebo keď je potrebná väčšia abstrakcia.

Pamätajte, že nikto nepozná váš projekt lepšie ako vy. Experimentujte, prispôsobujte sa a nebojte sa zmeniť svoj prístup, keď zistíte, čo funguje najlepšie. Vzory sú nástroje vo vašej vývojárskej výbave, takže ich používajte tam, kde majú najväčší vplyv.

Skúsili ste implementovať tieto vzory vo svojich projektoch? Čo fungovalo, čo nefungovalo a čo vás prekvapilo? Podelte sa o svoje skúsenosti, rád by som počul, ako štruktúrujete svoje aplikácie Laravel!