mvc的业务逻辑应该放哪里?

背景: 基于laravel的后台管理系统,CURD密集型业务

问题:当直接在控制器方法中调用orm处理业务逻辑时,代码复用性差,控制器层很肥

尝试解决1:新建一个model层,将原先在控制器中的处理逻辑移到model中,包括数据校验

下面是model的基类

class BaseModel implements Responsable,UniqueCheckable
{
  // 业务模型应当都具备产生模型响应的能力
  use ModelResponse;
  // 当前业务CRUD操作密集,几乎都需要检验唯一性
  use CheckUniqueness;
  //业务模型以orm为驱动将数据进行持久化
  protected static $orm = null;
// 一个业务模型能被一个id唯一标识
  protected $primaryId;

  public function __construct($primaryId){
    $this->primaryId = $primaryId;
  }
  
// 实现UniqueCheckable接口,子类必须重写该方法
  public static function getPrimaryField(){
    exit(static::class." doesn't implements getPrimaryField function");
  }
}

其他模型类中的属性都是为了实现具体的方法服务的,下面是其中一个model的定义:

class Tables extends BaseModel
{
    private $tenantId;
    private $branchId;
    protected static $orm = 'App\DAL\Tenant\Tables';
    /**
     * @param int $tenantId [商户id]
     * @param int $branchId [门店id]
     */
    public function __construct($tenantId , $branchId){
      $this->tenantId = $tenantId;
      $this->branchId = $branchId;
    }
    /**
     * [参数初始化]
     * @param  array  $data [description]
     * @return [type]       [description]
     */
   public static function paramInit(array &$data){
     $data['pricePerHour']= array_key_exists('pricePerHour',$data)?$data['pricePerHour']:0;
     $data['minConsumption']= array_key_exists('minConsumption',$data)?$data['minConsumption']:0;
     $data['number']= array_key_exists('number',$data)?$data['number']:0;
   }
/**
 * @param array $data [description]
 */
    public function add(array $data){
      // 请求参数初始化
      static::paramInit($data);
       // 业务规则校验
      if(!static::isValueAllowed($this->branchId,'name',$data['name'])){
          return static::response(false,'该桌台已经存在');
      }
      $table = static::$orm::create(['tenantId'=>$this->tenantId,
                                'branchId'=>$this->branchId,
                                'position'=>$data['position'],
                                'minConsumption'=>$data['minConsumption'],
                                'number'=>$data['number'],
                                'pricePerHour'=>$data['pricePerHour'],
                                'name'=>$data['name']
                            ]);
      return $table?static::response(true,$table):static::response(false,'数据写入失败');
    }
}

该方法的问题:model层只是业务逻辑的封装?但有新的需求就往model中加新的方法,然后在控制器中调用,那么这个model类不就只是方法的堆积?

尝试解决2:initPHP框架中提出了dscv的架构,其实就是把业务逻辑放在service中,然后在控制器中调用service对象来完成请求的处理

这种方法正在考虑实施

尝试解决3: 在看到了这篇文章后:也许后端MVC的说法已经过时了,感觉作者正好说到了我的痛点,所以又打算把控制器层分割为控制器+service层,把model分割为使用orm的数据持久层和repository层。这几者之间的关系是repository调用orm进行数据持久化,service层通过repository实现相关操作,然后控制器层调用service处理请求。但是这时候对这个repository层感到疑惑,如果重新对orm实现的功能进行封装那么工作量将很大,而实际带来的好处也不是很显而易见的。所以我目前倾向于认为orm中对应的对象是数据库中的表,而repository对应的对象是领域驱动设计中谈到的entity或者aggregate,那么这个时候我是不是又该根据把m变为 领域层+repository+基础设施层?

这个问题已经纠结挺久了,谢谢各位大神的指教

Hong林伟本以为
浏览 3747回答 1
1回答

醉大侠

我只知道现在解决3应该是最合适的,其它的我给不了意见-_-
打开App,查看更多内容
随时随地看视频慕课网APP