Controller-Service-Model职责边界划分:实战中的三层解耦技巧

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
插件开发 96 浏览 22 回复

最近重构老插件时发现很多Controller里直接写SQL查询,Service层又混了页面渲染逻辑。分享下我们团队现在强制推行的分层规范:

1. Controller只做三件事:
- 接收请求参数(过滤+基础校验)
- 调用Service方法
- 返回响应/跳转

// 反例
function update_user() {
    $data = $_POST;
    if(empty($data['id'])) {
        wp_redirect('/error');
    }
    global $wpdb;
    $wpdb->update('users', $data); // 致命问题:SQL直接写在控制器
}

2. Service层黄金法则:
- 纯PHP业务逻辑(if/else/for等)
- 可调用多个Model方法组合业务
- 禁止出现SQL/HTML/HTTP相关代码

// 正例
class UserService {
    public function upgradeVip($userId) {
        $user = $this->userModel->find($userId);
        if($user->level < 3) {
            $this->userModel->updateLevel($userId, 3);
            $this->logModel->record($userId, 'VIP升级');
        }
    }
}

3. Model层严格限制:
- 只包含数据存取方法
- 每个方法对应单个原子操作
- 表名/字段名只在这一层出现

// 推荐写法
class UserModel {
    public function findByEmail($email) {
        return $wpdb->get_row(
            "SELECT * FROM {$this->table} WHERE email = %s", 
            sanitize_email($email)
        );
    }
}

特殊场景处理:
- 跨表事务放在Service层
- 复杂数据校验可抽离Validator类
- 视图渲染建议用单独Presenter层
记住:每当你犹豫代码该放哪层时,就说明当前分层还不够干净!

评论22
回复 · 22
阿夜
阿夜 初级赤羽栖云 · #20 ·
感谢分享!
NightOwl
NightOwl 新手璃海华章 · #19 ·
学到了,顶一下
CoolKid🌸
CoolKid🌸 初级璃梦花海 · #18 ·
支持了~
Kate
Kate 新手时梦乐园 · #17 ·
学到了,顶一下
WadeWave
WadeWave 新手 · #16 ·
学到了,顶一下
GoldenHour
GoldenHour 新手 · #15 ·
支持了~
SunnyDay
SunnyDay 新手流金绮梦 · #14 ·
已解决,谢谢楼主
迷路的星星
迷路的星星 新手赤羽栖云 · #13 ·
同求,期待更新
温柔的白云
温柔的白云 初级 · #12 ·
感谢分享!
Paul
Paul 新手 · #11 ·
写得很清楚,收藏了
IvySky
IvySky 初级 · #10 ·
支持了~
浪漫的草莓
浪漫的草莓 新手 · #9 ·
已解决,谢谢楼主
Ivy
Ivy 初级 · #8 ·
支持了~
SkyWalker
SkyWalker 新手璃海华章 · #7 ·
已解决,谢谢楼主
快乐的草莓
快乐的草莓 初级 · #6 ·
已解决,谢谢楼主
Miles
Miles 新手漫步繁花 · #5 ·
感谢分享!
晚风里的月亮
晚风里的月亮 新手圣羽星庭 · #4 ·
感谢分享!
MayaPark
MayaPark 初级 · #3 ·
同求,期待更新
YukiRain
YukiRain 新手 · #2 ·
已解决,谢谢楼主
知夏
知夏 新手圣羽星庭 · #1 ·
写得很清楚,收藏了
1 2
微信客服 微信客服