deyan-ardi / laravel-layerize
用于在Laravel中实现分层架构的包
Requires
- php: ^7.3|7.4|^8.0|^8.1|^8.2
README
什么是分层架构
在Laravel框架中,标准使用的是一种架构,即MVC(模型 - 视图 - 控制器)。这种架构也包含在实现分层架构的示例中,但当我们只实施MVC时,会遇到一些障碍。
这个问题主要在开始开发复杂且持续更新的基于Laravel的应用时遇到,因为所有业务逻辑都位于控制器中,MVC架构无法整体处理。因此,如果开发团队发生变化,新加入的团队将花费大量时间学习之前的代码。
克服这一问题的方法之一是将标准Laravel框架架构发展到更干净的代码架构,但问题是,这没有官方标准,许多新手程序员发现很难学习。
使用Laravel Layerize,您可以将业务逻辑与控制器分离,并将您的代码组织成清晰、独立的层。此包提供了一种现成的目录结构,以及根据各自功能组织代码的最佳实践方法。
Laravel Layerize包有多个层次,包括
- 表示层:最接近用户或“表示”的层。其主要任务包括处理用户交互,例如接收用户输入、显示视图和向用户发送响应。该层包含路由、控制器、DTO或表单验证等组件。
- 业务层:包含应用程序的业务逻辑或业务规则的层。其主要任务包括协调业务流程、执行验证、做出决策和处理数据。此层是技术无关的,负责将业务逻辑与其他实现细节隔离。该层包含用例等组件。
- 持久层:负责从持久资源(如数据库或文件存储)存储和检索数据的层。其主要任务是执行CRUD(创建、读取、更新、删除)操作。此层提供访问持久资源的接口,并使应用程序能够存储和检索数据。该层包含命令服务、查询服务、数据表服务以及其他根据需求的服务组件。
- 数据库层:直接引用应用程序使用的数据库系统的层。它涉及数据库服务器、数据库模式、表和查询等组件。此层作为支持持久层在数据库中存储和检索数据的底层基础设施。
通过采用Laravel Layerize,应用程序可以组织良好,具有清晰的架构,并且每个层之间有明确的职责。这允许更容易的维护、更有结构的开发,并增加了应用程序的可扩展性和灵活性。
Laravel支持版本
系统要求
- PHP版本 "^7.3|7.4|^8.0|^8.1|^8.2"
- 文件(默认由Laravel Illuminate提供)
如何安装
-
打开终端,运行此命令
composer require deyan-ardi/laravel-layerize --dev
-
安装完成后,您可以通过运行以下命令开始使用此包
如何更新
-
打开终端,运行此命令
composer update deyan-ardi/laravel-layerize
如何使用(按层提供文档)
信息
此包支持文件夹生成,您可以使用"/"在文件夹中创建文件(例如:Admin/KonfigurasiController => 在Admin文件夹中创建KonfigurasiController类)
表示层
路由
路由没有变化,您可以根据Laravel框架标准实现路由
DTO/验证
在 Laravel 框架中,DTO/验证由 FormRequest 处理。此包帮助您创建 FormRequest 框架,以便在进入 Controller 之前在用户请求端进行验证。要使用 Layerize 创建 FormRequest,请使用以下命令:
php artisan layerize:dto User/StoreUserRequest
上述命令的结果将生成一个名为 StoreUserRequest
的类,该类将被添加到 App/Http/Requests/User
文件夹中。
<?php namespace App\Http\Requests\User; use Illuminate\Foundation\Http\FormRequest; class StoreUserRequest extends FormRequest { // Dto/validation with example implementation public function authorize() { return true; } public function rules() { return [ // Validation rules ]; } protected function prepareForValidation() { $this->merge([ // prepare for validation ]); } public function messages() { return [ // custom message of validation ]; } public function attributes() { return [ // custom attributes of validation ]; } }
Controller
此包帮助您创建 Controller 框架,以便您可以向下一层发送请求。要使用 Layerize 创建 Controller,请使用以下命令:
php artisan layerize:controller UserController
上述命令的结果将生成一个名为 UserController
的类,该类将被添加到 App/Http/Controllers
文件夹中。
<?php namespace App\Http\Controllers; use App\Helpers\Json; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Throwable; class UserController extends Controller { // Controller code with example implementation public function __construct( // protected UserUseCase $userUseCase, ) { } public function index() { // Render from use case // return $this->userUseCase->renderIndex(); } public function datatable(Request $request) { try { // Render from use case // DB::beginTransaction(); // $datatable = $this->userUseCase->renderDatatable($request); // DB::commit(); // return $datatable; } catch (Throwable $th) { // DB::rollBack(); // return Json::error($th->getMessage()); } } public function create() { // Render from use case // return $this->userUseCase->renderCreate(); } // StoreUserRequest can be generate using layerize:dto public function store(StoreUserRequest $request) { try { // Render from use case // DB::beginTransaction(); // $this->userUseCase->execStore($request); // DB::commit(); // return redirect()->back()->with('success', "Data Successfully Added"); } catch(Throwable $th) { // DB::rollBack(); // return redirect()->back()->with('error', $th->getMessage()); } } public function edit(string $id) { // Render from use case // return $this->userUseCase->renderEdit($id); } // UpdateUserRequest can be generate using layerize:dto public function update(UpdateUserRequest $request, string $id) { try { // Render from use case // DB::beginTransaction(); // $this->userUseCase->execUpdate($request, $id); // DB::commit(); // return redirect()->back()->with('success', "Data Successfully Updated"); } catch(Throwable $th) { // DB::rollBack(); // return redirect()->back()->with('error', $th->getMessage()); } } public function delete(string $id) { try { // Render from use case // DB::beginTransaction(); // $this->userUseCase->execDelete($request); // DB::commit(); // return redirect()->back()->with('success', "Data Successfully Delete"); } catch(Throwable $th) { // DB::rollBack(); // return redirect()->back()->with('error', $th->getMessage()); } } }
业务层
用例
此包帮助您创建 UseCase 框架,以便您可以在应用程序中执行业务逻辑。要使用 Layerize 创建 UseCase,请使用以下命令:
php artisan layerize:usecase UserUseCase
上述命令的结果将生成一个名为 UserUseCase
的类,该类将被添加到 App/Http/UseCase
文件夹中。
<?php namespace App\Http\UseCase; use Illuminate\Http\Request; class UserUseCase { // Use case code with example implementation public function __construct( // protected UserQuery $userQuery, // protected UserCommand $userCommand, // protected UserDatatable $userDatatable, ) { } public function renderIndex() { // render view index // return view('index'); } public function renderDatatable(Request $request) { // render datatable // return $this->userDatatable->datatable($request); } public function renderCreate() { // render view create // return view('create'); } // StoreUserRequest can be generate using layerize:dto, but must same with request send by controller public function execStore(StoreUserRequest $request) { // exec store data // return $this->userCommand->store($request), } public function renderEdit(string $id) { // render view create // $findId = $this->userQuery->firstOrFail(['id' => $id]); // return view('edit', compact('findId')); } // UpdateUserRequest can be generate using layerize:dto, but must same with request send by controller public function execUpdate(UpdateUserRequest $request, string $id) { // exec store data // return $this->userCommand->update($request, $id), } public function execDelete(string $id) { // exec store data // return $this->userCommand->delete($id), } }
持久层
生成所有服务默认(查询服务,表格服务,命令服务)
此包帮助您构建所有默认服务以与数据库层交互。要使用 Layerize 使所有服务默认,请使用以下命令:
php artisan layerize:service UserPage/User --all
上述命令的结果将生成三个名为 UserQuery
、UserCommand
、UserDatatable
的类,它们将被添加到 App/Services/UserPage/User
文件夹中。
UserQuery.php
<?php namespace App\Services\UserPage\User; use App\Services\Service; class UserQuery extends Service { public function __construct() { // self::setModel(User::class); call your model class name to use general function list } // Other Query Service here public function getCustomQuery(string $id) { // Other code here if query not support in getByAttr method } }
UserCommand.php
<?php namespace App\Services\UserPage\User; use App\Services\Service; class UserCommand extends Service { // Command Service here // StoreUserRequest can be generate by layerize:dto, but must same with request send by UseCase public function store(StoreUserRequest $request) { // Code for store data } // UpdateUserRequest can be generate by layerize:dto, but must same with request send by UseCase public function update(UpdateUserRequest $request, string $id) { // Code for update data } public function delete(string $id) { // Code for delete data } }
UserDatatable.php
<?php namespace App\Services\UserPage\User; use App\Services\Service; class UserDatatable extends Service { // Datatable Service here public function datatable(Request $request) { // Datatable server side processing code here } }
生成单个服务
此包帮助您构建服务以与数据库层交互。要使用 Layerize 使服务默认,请使用以下命令:
php artisan layerize:service UserPage/ApiProvider
上述命令的结果将生成一个名为 ApiProvider
的类,该类将被添加到 App/Services/UserPage
文件夹中。
<?php namespace App\Services\UserPage; use App\Services\Service; class ApiProvider extends Service { // Your custom service code here }
数据库层
模型
模型没有变化,您可以根据 Laravel 框架标准实现模型。
通用查询服务函数
通过配置查询服务,我们提供了一些简单的自定义函数,这些函数可以在 UseCase 中使用,以加快查询数据库的过程。
配置
- 创建查询服务
- 在查询服务类构造函数中添加模型名称
... class UserQuery extends Service { public function __construct() { self::setModel(User::class); // add like this } ... }
- 在 UseCase 中调用查询服务
... class UserUseCase { public function __construct( protected UserQuery $userQuery ) { } ... }
- 一个查询服务只能与一个模型集成,您可以为服务创建多个查询服务实例。
FirstOrFail
-
默认参数
firstOrFail($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->firstOrFail(['id' => 5],['role'],'created_at','desc')
First
-
默认参数
first($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->first(['id' => 5],['role'],'created_at','desc')
Get
-
默认参数
get($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->get(['role_id' => 5],['role'],'created_at','desc')
GetCount
-
默认参数
getCount($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->getCount(['role_id' => 5],['role'],'created_at','desc')
Paginate
-
默认参数
paginate($perPage = 10, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->paginate(15, ['role_id' => 5],['role'],'created_at','desc')
Pluck
-
默认参数
pluck($column, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->pluck("name", ['id' => 5],['role'],'created_at','desc')
Chunk
-
默认参数
chunk($size, $callback, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')
-
示例用法
$this->userQuery->chunk(1000, function ($items) { foreach ($items as $item) { // Lakukan sesuatu dengan setiap item } }, ['category' => 'books'], ['author'], 'title', 'desc');
First Or New
-
默认参数
firstOrNew($where = [], $attributes = [])
-
示例用法
$this->userQuery->firstOrNew(['email' => 'example@example.com'], ['name' => 'John Doe'])
贡献
- GanaDev Com
- 开源,要贡献请阅读 CONTRIBUTING.md
版本
- v2.0.0
许可证
Laravel Layerize 是开源软件,许可协议为 MIT 许可证。