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

C++ 设计模式《统计辅助功能》

👨‍🎓 模式名称:访问者模式(Visitor)

👦 故事背景:

小明的系统上线后,业务越来越多。统计员小李的任务是每周统计:

  • 用户活跃数
  • 总订单收入
  • 好评评价数

但是这些业务对象(User, Order, Review)分属不同模块、由不同人维护,结构不同,统计逻辑也不同。

小李一开始采用了最直接的方法 —— 在每个类里写统计逻辑:

❌ 没有使用访问者模式的代码(耦合高、不易扩展)

1. 各业务类都写了 analyze() 方法,分析逻辑分散在每个类中
#include <iostream>
#include <vector>
#include <string>class User {
public:std::string name;int loginDays;bool isActive() const {return loginDays > 30;}void analyze(int& activeUserCount) {if (isActive()) {activeUserCount++;}}
};class Order {
public:int price;void analyze(int& totalRevenue) {totalRevenue += price;}
};class Review {
public:int score;void analyze(int& positiveReviewCount) {if (score >= 4) {positiveReviewCount++;}}
};
2. 小李的分析函数 👇
void doAnalysis(std::vector<User>& users, std::vector<Order>& orders, std::vector<Review>& reviews) {int activeUserCount = 0;int totalRevenue = 0;int positiveReviewCount = 0;for (auto& u : users) u.analyze(activeUserCount);for (auto& o : orders) o.analyze(totalRevenue);for (auto& r : reviews) r.analyze(positiveReviewCount);std::cout << "活跃用户数:" << activeUserCount << std::endl;std::cout << "总收入:" << totalRevenue << std::endl;std::cout << "好评数:" << positiveReviewCount << std::endl;
}

❌ 这会有什么问题?

问题点描述
❌ 逻辑分散每个类都负责“分析”自己的数据,导致功能散落四处
❌ 扩展困难如果要加一个“导出为 Excel 的功能”,又要修改每个类
❌ 违背开闭原则每个新的分析需求都意味着要修改所有业务类
❌ 违反单一职责原本只负责数据的业务类,现在还要处理“统计、导出”等行为

✅ 使用访问者模式:结构统一、处理分离

🧱 抽象访问者:数据分析器
class Order;
class User;
class Review;class AnalyticsVisitor {
public:virtual void visit(Order* order) = 0;virtual void visit(User* user) = 0;virtual void visit(Review* review) = 0;virtual ~AnalyticsVisitor() = default;
};
🧱 抽象业务对象(被访问者)
class VisitableEntity {
public:virtual void accept(AnalyticsVisitor* visitor) = 0;virtual ~VisitableEntity() = default;
};
🧱 具体业务对象
class Order : public VisitableEntity {
public:int price = 20;std::string category = "外卖";void accept(AnalyticsVisitor* visitor) override {visitor->visit(this);}
};class User : public VisitableEntity {
public:std::string name = "张三";int loginDays = 45;void accept(AnalyticsVisitor* visitor) override {visitor->visit(this);}
};class Review : public VisitableEntity {
public:int score = 4;std::string comment = "不错的服务";void accept(AnalyticsVisitor* visitor) override {visitor->visit(this);}
};
🧱 具体访问者:统计分析逻辑
class DataAnalyzer : public AnalyticsVisitor {
public:int orderCount = 0;int totalRevenue = 0;int activeUsers = 0;int positiveReviews = 0;void visit(Order* order) override {orderCount++;totalRevenue += order->price;}void visit(User* user) override {if (user->loginDays > 30)activeUsers++;}void visit(Review* review) override {if (review->score >= 4)positiveReviews++;}void report() {std::cout << "订单数:" << orderCount << std::endl;std::cout << "总收入:" << totalRevenue << std::endl;std::cout << "活跃用户数:" << activeUsers << std::endl;std::cout << "好评数:" << positiveReviews << std::endl;}
};
🚀 使用示例
int main() {std::vector<VisitableEntity*> system = {new Order(), new User(), new Review(),new Order(), new User(), new Review()};DataAnalyzer analyzer;for (auto entity : system) {entity->accept(&analyzer);}analyzer.report();for (auto e : system) delete e;return 0;
}

✅ 使用访问者模式的优势

优势描述
👑 开闭原则新增分析逻辑时,只加新的 Visitor 类,不动原有结构
🤝 统一接口所有业务对象统一接受访问者
🧹 逻辑清晰分析逻辑集中在访问者类中,业务对象职责单一
🛠️ 易扩展可以创建多个访问者用于不同目的(如导出、展示)
http://www.dtcms.com/a/593584.html

相关文章:

  • 【技术分享】ComfyUI中protobuf版本兼容性问题的优雅解决方案:猴子补丁实战
  • Redis 高级篇(未完结1/3)
  • 华为OD机试 真题 - 【国际移动用户识别码(IMSI)匹配】 - 双机位A卷 (Python C++ JAVA JS GO)
  • 自动更新工期触发器(MYSQL)
  • 企业网站建设的方式有哪些方式网页设计版权怎么写
  • 关键词解释:范数(Norm)
  • 用Python生成个性化的电子邮件签名
  • [PowerShell入门教程] 第2天:变量、管道、对象操作与执行策略详解
  • 做网站运营的职业生涯规划wordpress 水印插件
  • 护照阅读器在酒店行业的应用
  • 继承的概念及使用
  • 建网站的地址手工制作小船
  • 技术选型深度评估:“六行神算”平台在医疗AI项目中的架构适配性
  • VLAN 和 VXLAN
  • PC微信 device uuid 算法
  • 外国网站的浏览器下载网站程序是什么意思
  • 【Docker多节点部署】基于“配置即身份“理念的 Docker 多节点 StarRocks 高可用集群自动化部署方案
  • 如何选择适合企业的数据仓库建模工具?​
  • Ethernet ip转SPI嵌入式板卡-让机器人与单片机互相联动
  • 免费推广网站大全下载安装南山网站-建设深圳信科
  • 【ZeroRange WebRTC】OpenSSL 与 WebRTC:原理、集成与实践指南
  • AnyVP*:企业级远程办公SSL深度技术解析
  • 重庆营销型网站建设多少钱学校网站功能描述
  • Spring @Component 和 @Bean 的区别与最佳实践
  • 怎么给自己公司做网站小影wordpress
  • C# 特性详解
  • 《 Linux 修炼全景指南: 六 》软件包管理器
  • QNAP紧急修复Pwn2Own 2025比赛中遭利用的7个0Day漏洞
  • 大学学部网站建设工作深圳牌申请网站空间
  • LeetCode算法学习之乘积最大子数组