当您没有针对该功能的指定模型时,将业务逻辑放在哪里? Laravel

Where to put business logic when you don't have a specified model for that feature? Laravel

我正在尝试改进我的代码 OOP 明智。 我倾向于将我的一些业务逻辑放在我的控制器中。

有些人告诉我这是不可取的。

我知道,例如,当您使用 Posts 时。您可以简单地将业务逻辑放入 Post.php 模型中。

我现在有一个功能,我上传一个 .xlsx 文件,如果 .xlsx 的格式正确,必须检查和验证它​​。

目前在ScheduleController@storeDeliveryXlsx里面。

但是我没有为此指定的模型来存储验证?

这是需要存储库设计模式的地方吗?还是可以创建一个不与数据库通信的模型,例如:DeliveryFile.php 我将稍后可以在整个应用程序中使用的逻辑放在其中,如下所示:DeliveryFile::validate($file);DeliveryFile::upload(file); .

我想我可能会在 .xlsx 上对多个实例重复使用相同的验证。所以我想做一些类似 Model::validate($file); 的事情。但是我不知道把代码放在哪里。

短语 I now have a feature 会在您编写的代码的生命周期中不断重复。拥有独立的控制器、服务、模型 类、OOP 设计、模块化代码在这方面肯定会有所帮助。现在它可能更容易,但随着时间的推移它会变得越来越困难

在这种情况下,我个人会推荐使用服务。服务 class 本质上是用于您可以在多个控制器中重复使用的通用功能。 Service 层是一种设计模式,可帮助您将共享逻辑抽象为公共服务,即我们的新服务 Class.

因此,在您的实例中,您可以拥有一个服务 class,例如 ExcelValidator,然后使用类似于以下内容的方法来构建您的方法。

<?php

namespace App/Services;

class ExcelValidatorService
{

  public function validate($file) 
  {
    // our validate logic
  }

}

然后在您的控制器或模型中,您可以调用 ExcelValidator 服务来实现您的重复验证逻辑。

最近我遇到了类似的问题,在我的情况下,我需要使用 Restful API.

作为模型

在composer.json下我添加了autoload

"psr-4": {
    "App\": "app/",
    "MYCOMP\": "app/MYCOMP/"
},

在应用程序文件夹下,我添加了 MYCOMP 文件夹,其中包含两个子文件夹 Providers 和 Restmodels。

在 config/app.php providers 数组中我只添加了:

MYCOMP\Providers\RestModelServiceProvider::class,

在 app/MYCOMP/Providers/RestModelServiceProvider.php 中,我为我的其余模型注册了所有提供者和外观:

public function register()
{
    $loader = \Illuminate\Foundation\AliasLoader::getInstance();

    $models = glob( realpath(__DIR__."/../") ."/RestModels/*/*RestModel.php");
    foreach($models as $model){
        $bnmodel = basename($model);

        if($bnmodel !== "BaseRestModel.php" && $bnmodel !== "BaseFacadeRestModel.php"){
            list($n, $niente) = explode("RestModel.php", $bnmodel);
            list($bnnoext, $niente) = explode(".php", $bnmodel);
            $res = $n.'Repository';
            $fold = basename(dirname($model));
            $nc = "\MYCOMP\RestModels\".$fold."\".$bnnoext;  
            $this->app->bind($res, function($app) use ($nc) {     
                return new $nc;
            });               
            $loader->alias($res, $nc."Facade");
        }
    }
}

此代码特定于我的项目以及我构建文件夹的方式。 对于所有其余模型,我有两个文件:

  • app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModel.php
  • app/MYCOMP/RestModels/{ModelName}/{ModelName}RestModelFacade.php

唯一的例外是:BaseRestModel 和 BaseFacadeRestModel 这些 类 由所有 RestModel 和 RestModelFacade 扩展。所以我会在 BaseRestModel 下实现类似验证的东西。

BaseFacadeRestModel 仅包含:

<?php

namespace MYCOMP\RestModels\Base;
use Illuminate\Support\Facades\Facade;

class BaseFacadeRestModel extends Facade{
    private $facadeName;

    protected static function getFacadeName(){
        list($senzasuffisso, $niente) = explode("RestModelFacade", static::class);

        $nc = last(explode("\", $senzasuffisso));
        return $nc;
    }

    protected static function getFacadeAccessor() {
        return static::getFacadeName().'Repository'; 
    }
}

因此所有其他 Facades 只需扩展 BaseFacadeRestModel 即可工作。