当前位置: 首页 > web >正文

重构 MVC:让经典架构完美适配复杂智能系统的后端业务逻辑层(内附框架示例代码)

🔥挖到宝!这个 AI 学习网站简直神仙级存在!

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。https://www.captainbed.cn/inc


软件开发—重构MVC


目录

软件开发—重构MVC

一、传统MVC架构

二、改进MVC架构

1.核心改进思路:拆分Model层,明确职责边界

2.关键改进点:让复杂业务逻辑“有处安放”

3.改进后架构对业务逻辑复杂平台的适配性


一、传统MVC架构

        传统的MVC是一种简单直观的架构模式,适合简单的系统应用。例如下面所展示的开源学习项目(https://gitee.com/keanu_zhang/load-balancing-oj-system)“负载均衡OJ系统”早期就是采用经典的MVC架构模式。

简单的”负载均衡OJ系统“

        但纯MVC架构的核心问题是Model层职责过重,因为它既存储数据又包含业务逻辑及模型服务,在业务复杂的系统(蒙古语综合智能平台)中容易导致代码逻辑交织,难以维护扩展。

二、改进MVC架构

        针对这一问题,可通过“分层拆分 Model 层 + 引入领域逻辑封装 + 强化服务协作”进行改进,使其适配复杂业务的系统平台。

1.核心改进思路:拆分Model层,明确职责边界

        将传统MVC的“Model”拆分为数据层、领域层、应用层,让每一层专注单一职责,避免业务逻辑与数据处理混杂。改进分层后,以蒙古语综合智能平台为例,其软件平台后端架构图如下。

蒙古语综合智能平台服务端架构图

其系统服务端下包括文件夹MCIPserver_bll(服务端-业务逻辑层)和MCIPserver_mms(服务端-多模型服务)。

首先:在文件夹MCIPserver_bll(服务端-业务逻辑层)下包括文件BLL.cpp、BLL_view.hpp(视图)、BLL_model.hpp(模型)及BLL_controller.hpp(控制器);还包括文件夹MODEL_tl(模型-三层)。

(1)MCIPserver_bll文件夹->BLL.cpp文件

#include<iostream>
//按开发需求进行头文件的补充...#include"../MCIP_tool/httplib.h"
#include"./BLL_controller.hpp"using namespace httplib;
using namespace BLL_controller;int main()
{Server svr;controller ctl;     //控制层/************************* 1.进行前端请求的获取(GET)及后端服务的推送(POST);***********************/svr.set_base_dir("../MCIPclient_ivl/IVL_wwwroot");svr.listen("0.0.0.0",8080);return 0;
}

(2)MCIPserver_bll文件夹->BLL_view.hpp文件

#pragma once#include<iostream>
#include<string>
#include<vector>
#include <ctemplate/template.h>
//按开发需求进行头文件的补充...#include"./BLL_model.hpp"namespace BLL_view
{using namespace BLL_model;/************************* 1.进行前端关键视图界面的渲染,如几大核心功能界面模块;***********************/class view{public:view(){}~view(){}public://页面渲染函数接口private:  model mdl;};
}

(3)MCIPserver_bll文件夹->BLL_controller.hpp文件

#pragma once#include<iostream>
#include<string>
#include<vector>
#include <jsoncpp/json/json.h>
//按开发需求进行头文件的补充...#include"./BLL_view.hpp"
#include"./BLL_model.hpp"namespace BLL_controller
{using namespace BLL_model;using namespace BLL_view;/************************* 1.接收请求、参数校验、调用应用层、返回结果;***********************/class controller{public:controller(){}~controller(){}public://以请求情感分析模型为例,模拟数据流驱动过程std::string RequestSentimentAnalysisModel(/*言语数据及多模态标签*/){//1.进行请求std::string result=mdl.SentimentAnalysisModelService(/*言语数据及多模态标签*/);//8.分析结果返回return result;}//其它请求函数接口private:model mdl;  view viw;  //视图层};
}

(4)MCIPserver_bll文件夹->BLL_model.hpp文件

#pragma once#include<iostream>
#include<string>
#include<vector>
#include<unistd.h>
#include<cstdio>
#include<cstdlib>
//按开发需求进行头文件的补充...#include"./MODEL_tl/TL_al.hpp"
#include"./MODEL_tl/TL_dl.hpp"
#include"./MODEL_tl/TL_tl.hpp"namespace BLL_model
{using namespace TL_al;/************************* 1.将传统 MVC 的 “Model” 拆分为数据层、领域层、应用层,让每层专注单一职责,避免业务逻辑与数据处理混杂。***********************/class model{public:model(){}~model(){}public:     //调用数据层//负责数据CRUD,与数据库交互;public:     //调用领域层//封装核心业务规则;public:     //调用应用层//协调领域层与数据层,实现用户用例及核心功能;std::string SentimentAnalysisModelService(/*言语数据及多模态标签*/){//2.调用应用层的相关模型函数接口std::string result=alm.processSentimentAnalysis(/*言语数据及多模态标签*/);//7.分析结果返回return result;}private:al_MultimodelProcessService alm;};
}

在文件夹MODEL_tl(模型-三层)下包括文件TL_al.hpp(应用层)、文件TL_dl.hpp(数据层)及文件TL_tl.hpp(领域层)。这三层从传统的 MVC 架构 “Model” 下进行拆分得来。在这里我们以文件TL_al.hpp(应用层)为例去简单展示后端数据流的业务逻辑情况,而文件TL_dl.hpp(数据层)及文件TL_tl.hpp(领域层)中的代码按示例进行相应开发书写即可。

(5)MCIPserver_bll文件夹->MODEL_tl文件夹->TL_al.hpp文件

#pragma once#include<iostream>
#include<string>
#include<vector>
//按开发需求进行头文件的补充...#include"../../MCIPserver_mms/MMS_SA/sa.hpp"typedef int MultimodalLabel;namespace TL_al
{using namespace sa;/************************* 1.model->应用层:多模型进程服务类* 通过调用该类中的功能函数接口,从而实现相应的AI模型服务;***********************/class al_MultimodelProcessService{private:sa_text _sa_text;sa_voice _sa_voice;sa_image _sa_image;sa_video _sa_video;public://情感分析(为例)std::string processSentimentAnalysis(std::string linguisticData,MultimodalLabel label){//多模态标签为1->文本,标签为2->语音,标签为3->图像,标签为4->视频;if(label==1){//3.调用相关模型,执行文本情感分析服务;_sa_text.xxx(/*言语数据*/);//6.分析结果返回}else if(label==2){//3.调用相关模型,执行语音情感分析服务;_sa_voice.xxx(/*言语数据*/);//6.分析结果返回}else if(label==3){//3.调用相关模型,执行图片情感分析服务;_sa_image.xxx(/*言语数据*/);//6.分析结果返回}else if(label==4){//3.调用相关模型,执行视频情感分析服务;_sa_video.xxx(/*言语数据*/);//6.分析结果返回}}//手写体识别void processHandWriting(){}//机器翻译void processMachineTranslate(){}//语音合成void processLanguageSynthesis(){}};/************************* 2.model->应用层:...***********************/
}

其次:在文件夹MCIPserver_mms(服务端-多模型服务)下包括我们整个系统多个多模态模型的文件。下面我们以情感分析文件夹MMS_SA(多模型服务-情感分析)为例,展示其下的sa.hpp(情感分析)文件,该文件将会根据相应的请求,通过API接口来调用该文件目录下相应的AI模型,从而实现用户的功能需求。

(6)MCIPserver_mms文件夹->MMS_SA文件夹->sa.hpp文件

#pragma once#include<iostream>
#include<string>
//按开发需求进行头文件的补充...namespace sa
{class sa_text{public://4.相关模型函数API//5.模型分析后,得出相应的结果进行返回private:};class sa_voice{public:     //4.相关模型函数API//5.模型分析后,得出相应的结果进行返回private:};class sa_image{public://4.相关模型函数API//5.模型分析后,得出相应的结果进行返回private:};class sa_video{public://4.相关模型函数API//5.模型分析后,得出相应的结果进行返回private:};
}

2.关键改进点:让复杂业务逻辑“有处安放”

(1)引入“领域服务”封装核心业务逻辑

        对于传统 MVC 的 Model 层(如TranslationModel)既包含 “源文本、目标语言” 等数据,又包含 “调用 AI 模型、解析蒙古文语法” 等复杂逻辑,导致 Model 臃肿这些问题。所以我们通过“数据部分”和“逻辑部分”这两个模块去对其进行改进。数据部分采用实体类存储纯数据,如:MongolianText含content文本内容、encoding编码格式等属性,而无业务方法;逻辑部分用领域服务封装业务规则,其独立于数据仅处理逻辑。

// 1.数据层(纯数据)
class MongolianText {
private:std::string content; // 蒙古语文本内容std::string encoding; // 编码格式(如Unicode)
public:// get/set方法std::string getContent() const { return content; }void setContent(const std::string& content){ this->content = content; }std::string getEncoding() const { return encoding; }void setEncoding(const std::string& encoding) { this->encoding = encoding; }
};// 2.领域层(纯逻辑)
class SentimentResult;    // 前向声明情感分析结果类       
class MongolianSentimentAnalysisService {
public:// 蒙古语情感分析核心逻辑:结合AI模型与蒙古语语义规则SentimentResult analyze(const MongolianText& text);
};// 情感分析结果类
class SentimentResult {
private:// 情感标签(假设为枚举类型,实际实现需定义)int sentimentLabel; // SentimentResult类double confidence;  // 置信度
public:SentimentResult(int sentimentLabel, double confidence) : sentimentLabel(sentimentLabel), confidence(confidence) {}int getSentimentLabel() const { return sentimentLabel; }double getConfidence() const { return confidence; }
};// 实现分析方法
SentimentResult MongolianSentimentAnalysisService::analyze(const MongolianText& text) {// 1. 调用AI模型获取初步结果// 2. 用蒙古语否定词规则修正结果(如"高兴"前加"不"变为"悲伤")// 3. 返回最终情感标签// 纯占位实现,实际逻辑需补充return SentimentResult(0, 0.0); // 假设0表示中性情感
}

(2)用“应用服务”串联跨领域流程

        对于复杂业务常涉及多步操作(如 “用户手写蒙古文→识别→翻译→语音合成”),传统 MVC 的 Controller 层直接写这些逻辑会导致代码冗长、复用性差这些问题。所以我们通过新增应用服务专门负责跨层/跨领域的流程协调,Controller 层仅调用应用服务,不写具体逻辑。

// 前向声明各类
class MongolianText;
class TranslationResult;
class ProcessResult;
class HandwritingRecognitionService;
class TranslationService;
class VoiceSynthesisService;
class HistoryRecordDataService;// 应用服层(协调多步骤流程)
class MultimodalProcessService {
private:HandwritingRecognitionService* recognitionService; // 手写识别领域服务TranslationService* translationService; // 翻译领域服务VoiceSynthesisService* voiceService; // 语音合成领域服务HistoryRecordDataService* historyDataService; // 历史记录数据服务public:// 构造函数(替代依赖注入)MultimodalProcessService(HandwritingRecognitionService* recognition,TranslationService* translation,VoiceSynthesisService* voice,HistoryRecordDataService* history) : recognitionService(recognition), translationService(translation),voiceService(voice),historyDataService(history) {}// 完整流程:手写→识别→翻译→语音合成→保存记录ProcessResult processHandwriting(const std::string& imageBase64);
};// Controller层(仅调用应用层服务)
class MultimodalController {
private:MultimodalProcessService* processService;public:// 构造函数MultimodalController(MultimodalProcessService* service) : processService(service) {}// 处理请求的方法struct Result {bool success;ProcessResult* data;static Result success(ProcessResult* data) {return {true, data};}};Result process(const std::string& image);
};

(3)强化“数据层”与业务逻辑的解耦

        对于传统 MVC 中,Model 层常直接包含 SQL 操作,导致业务逻辑与数据库耦合(换数据库需改大量代码)这些问题。所以我们数据层用 Repository 模式封装数据库操作,对外提供抽象接口,屏蔽具体存储细节;因此领域层和应用层仅依赖 Repository 接口,不关心底层是 MySQL 还是 MongoDB。

// 翻译记录实体类
class TranslationRecord {// 类的具体实现保持不变
};
// 仓储接口(抽象数据操作)
class TranslationHistoryRepository {
public:virtual ~TranslationHistoryRepository() = default;virtual void save(const TranslationRecord& record) = 0; // 保存翻译记录virtual std::vector<TranslationRecord> findByUserId(const std::string& userId) = 0; // 查询用户历史
};// MySQL实现(数据层细节)
class MysqlTranslationHistoryRepository : public TranslationHistoryRepository {
public:void save(const TranslationRecord& record) override {// 具体SQL逻辑:INSERT INTO ...}std::vector<TranslationRecord> findByUserId(const std::string& userId) override {// 具体SQL逻辑:SELECT * FROM ...return {};}
};// 应用层(不依赖MySQL)
class TranslationHistoryService {
private:std::unique_ptr<TranslationHistoryRepository> repository; // 依赖接口,而非具体实现public:explicit TranslationHistoryService(std::unique_ptr<TranslationHistoryRepository> repo): repository(std::move(repo)) {}void saveRecord(const TranslationRecord& record) {repository->save(record); // 无需关心用什么数据库}
};

(4)引入“策略模式”处理多变业务规则

        对于蒙古语平台的业务规则可能多变,如翻译模型可能切换、情感分析算法可能升级等,传统 MVC 中硬编码规则会导致修改成本高这个问题。所以我们对多变的逻辑用策略模式封装为可替换的“策略”,通过配置动态选择,即支持“自研模型”和“第三方API”两种策略。

// 翻译策略接口(父类)
class TranslationStrategy {
public:virtual ~TranslationStrategy() = default;virtual std::string translate(const std::string& mongolianText, const std::string& targetLang) = 0;
};// 策略1:自研翻译模型(子类)
class SelfDevelopedTranslationStrategy : public TranslationStrategy {
public:std::string translate(const std::string& mongolianText, const std::string& targetLang) override {// 具体实现逻辑return "自研模型翻译结果";}
};
// 策略2:第三方翻译API(子类)
class ThirdPartyTranslationStrategy : public TranslationStrategy {
public:std::string translate(const std::string& mongolianText, const std::string& targetLang) override {// 具体实现逻辑return "第三方API翻译结果";}
};// 应用层动态选择策略
class TranslationService {
private:std::unique_ptr<TranslationStrategy> strategy;public:// 构造时通过配置选择策略(如VIP用户用自研模型,普通用户用第三方)explicit TranslationService(const std::string& strategyType) {if (strategyType == "self") {strategy = std::make_unique<SelfDevelopedTranslationStrategy>();} else {strategy = std::make_unique<ThirdPartyTranslationStrategy>();}}std::string translate(const std::string& text, const std::string& targetLang) {return strategy->translate(text, targetLang); // 调用策略}
};

3.改进后架构对业务逻辑复杂平台的适配性

        通过 “拆分 Model 层为应用层 + 领域层 + 数据层”“引入 Repository 解耦存储”“用策略模式处理多变规则”,传统 MVC 被改造为 **“职责清晰、逻辑隔离、易于扩展”** 的架构,既能承载蒙古语平台的复杂业务逻辑、如:蒙古文特殊逻辑隔离处理、多模态功能协同交互、AI模型迭代集成等,又避免了代码臃肿和耦合问题。


http://www.xdnf.cn/news/16332.html

相关文章:

  • 【MacOS】发展历程
  • HTTP 请求方法有哪些?
  • 《基于电阻抗断层扫描(EIT)驱动的肌肉骨骼模型表征人体手臂动态意图用于人机交互》论文解读
  • 当人机交互迈向新纪元:脑机接口与AR/VR/MR的狂飙之路
  • Spring Cloud Gateway 服务网关
  • 2025年第四届创新杯(原钉钉杯)赛题浅析-助攻快速选题
  • Android Studio 2024 内嵌 Unity 3D 开发示例
  • 【第四章:大模型(LLM)】01.神经网络中的 NLP-(1)RNN、LSTM 和 GRU 的基本原理和应用
  • 全国产化5G-A低空经济基座
  • 【Unity笔记】OpenXR 之VR串流开发笔记:通过RenderTexture实现仅在PC端展示UI,在VR眼镜端隐藏UI
  • 大模型进阶面试题
  • 车载 CAN-Bus 数据记录仪说明书
  • 【C语言进阶】一篇文章教会你文件的读写
  • 【unitrix】 6.16 非负整数类型( TUnsigned )特质(t_unsingned.rs)
  • 电子电子架构 --- 软件项目的开端:裁剪
  • Java面试题(中等)
  • Javascript NaN Symbol BigInt
  • TDengine 转化类函数 CAST 用户手册
  • 7.24 C/C++蓝桥杯 | 排序算法
  • Android15或AndroidU广播的发送流程
  • 星慈光编程虫2号小车讲解第三篇--附件概述
  • 深入理解 IO 多路复用:从 select 到 epoll
  • MySQL---索引、事务
  • VUE2 学习笔记5 动态绑定class、条件渲染、列表过滤与排序
  • 【全新上线】境内 Docker 镜像状态监控
  • 秋招Day18 - MyBatis - 基础
  • C语言转义字符‘\\‘‘ 解析与常见误区
  • 六种经典智能优化算法(PSO/GWO/WOA/HHO/DBO/SSA)无人机(UAV)三维路径规划,Matlab代码实现
  • TimeXer - 重新审视时序预测内的外生变量
  • 【LeetCode数据结构】二叉树的应用(一)——单值二叉树问题、相同的树问题、对称二叉树问题、另一棵树的子树问题详解