背景: 基于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+基础设施层?
这个问题已经纠结挺久了,谢谢各位大神的指教
醉大侠