deyan-ardi/laravel-layerize

用于在Laravel中实现分层架构的包

v2.0.0 2023-06-27 07:59 UTC

This package is auto-updated.

Last update: 2024-09-27 11:54:04 UTC


README

Laravel PHP

什么是分层架构

Gambar

在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

上述命令的结果将生成三个名为 UserQueryUserCommandUserDatatable 的类,它们将被添加到 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 中使用,以加快查询数据库的过程。

配置

  1. 创建查询服务
  2. 在查询服务类构造函数中添加模型名称
...
class UserQuery extends Service
    {
        public function __construct()
        {
            self::setModel(User::class); // add like this
        }

        ...
    }
  1. 在 UseCase 中调用查询服务
...
  class UserUseCase
    {
        public function __construct(
            protected UserQuery $userQuery
        )
        {
            
        }

        ...
    }
  1. 一个查询服务只能与一个模型集成,您可以为服务创建多个查询服务实例。

FirstOrFail

  1. 默认参数 firstOrFail($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->firstOrFail(['id' => 5],['role'],'created_at','desc')

First

  1. 默认参数 first($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->first(['id' => 5],['role'],'created_at','desc')

Get

  1. 默认参数 get($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->get(['role_id' => 5],['role'],'created_at','desc')

GetCount

  1. 默认参数 getCount($where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->getCount(['role_id' => 5],['role'],'created_at','desc')

Paginate

  1. 默认参数 paginate($perPage = 10, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->paginate(15, ['role_id' => 5],['role'],'created_at','desc')

Pluck

  1. 默认参数 pluck($column, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->pluck("name", ['id' => 5],['role'],'created_at','desc')

Chunk

  1. 默认参数 chunk($size, $callback, $where = [], $with = [], $orderBy = null, $orderDirection = 'asc')

  2. 示例用法

$this->userQuery->chunk(1000, function ($items) {
    foreach ($items as $item) {
        // Lakukan sesuatu dengan setiap item
    }
}, ['category' => 'books'], ['author'], 'title', 'desc');

First Or New

  1. 默认参数 firstOrNew($where = [], $attributes = [])

  2. 示例用法

$this->userQuery->firstOrNew(['email' => 'example@example.com'], ['name' => 'John Doe'])

贡献

版本

  • v2.0.0

许可证

Laravel Layerize 是开源软件,许可协议为 MIT 许可证