背景: 基于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+基礎設施層?
這個問題已經糾結挺久了,謝謝各位大神的指教