🔥挖到宝!这个 AI 学习网站简直神仙级存在!
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。前言 – 人工智能教程
软件开发—重构MVC
目录
一、传统MVC架构
传统的MVC是一种简单直观的架构模式,适合简单的系统应用。例如下面所展示的开源学习项目(https://gitee.com/keanu_zhang/load-balancing-oj-system)“负载均衡OJ系统”早期就是采用经典的MVC架构模式。

但纯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 被改造为 **“职责清晰、逻辑隔离、易于扩展”** 的架构,改进后的MVC架构图如下。其既能承载蒙古语平台的复杂业务逻辑、如:蒙古文特殊逻辑隔离处理、多模态功能协同交互、AI模型迭代集成等,又避免了代码臃肿和耦合问题。
