插件分层实战:Service层到底该放业务逻辑还是数据组装?
最近重构老插件时发现Service层越来越臃肿,仔细分析发现很多同事把两类代码混在一起:
典型问题代码:
class UserService {
public function getUserWithOrders($uid) {
// 数据获取
$user = UserModel::find($uid);
$orders = OrderModel::where('uid', $uid)->get();
// 业务逻辑
if($user->vip_level > 3) {
$orders = $this->applyVipDiscount($orders);
}
// 数据组装
return [
'user' => $user->toArray(),
'orders' => array_map(function($order){
return [
'id' => $order->id,
'price' => $order->price * 0.8 // 折扣计算
];
}, $orders)
];
}
}
推荐拆分方案:
1. Model层:纯数据存取class UserModel {
public static function getWithOrders($uid) {
return self::with('orders')->find($uid);
}
}
2. Service层:只处理业务规则
class DiscountService {
public function applyVipPolicy($orders, $vipLevel) {
return $vipLevel > 3
? array_map(fn($o) => $o->setAttribute('discount', 0.8), $orders)
: $orders;
}
}
3. Controller层:组合调用+数据格式化
class UserController {
public function profile() {
$data = UserModel::getWithOrders($uid);
$data['orders'] = (new DiscountService())
->applyVipPolicy($data['orders'], $data['user']->vip_level);
return response()->json([
'user' => UserTransformer::format($data['user']),
'orders' => OrderTransformer::collection($data['orders'])
]);
}
}
关键原则:Service层应该像调味料,Model层提供原料,Controller负责摆盘。当需要新增折扣类型时,只需修改DiscountService,保持Model稳定。
最新打赏

