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

模块互相依赖问题解决的一个记录

背景:

工作以后,为了让自己更好的理解业务代码。

都会将代码抽象分解进行理解。

解耦、可扩展 都是考虑代码设计良好与否的非常重要因素。

之前设计的一个项-目,结合对大佬设计的框-架认识、和自己的经验理解。设计一个模块互相依赖的项目。当时设计的效果,解耦和可扩展效果都还不错。

然后今天问了下大-模型,如何解决模块互相依赖的问题,发现跟大模型设计的思路竟然一致。在此记录一下:

解决方案:接口 + 依赖注入 + 工厂模式

核心思想

  1. 定义共同接口:A和B都依赖于抽象接口,而不是对方的具体实现
  2. 使用依赖注入:通过Setter方法注入对方的接口
  3. 使用工厂管理依赖:通过ServiceManager确保依赖关系正确设置

完整实现示例

1. 接口定义(common_interface.h)
#pragma onceclass ICommonInterface {
public:virtual ~ICommonInterface() = default;virtual void doSomething() = 0;
};
2. A的接口(a_interface.h)
#pragma once
#include "common_interface.h"class IA : public ICommonInterface {
public:virtual void callB() = 0;  // A需要调用B的方法
};
3. B的接口(b_interface.h)
#pragma once
#include "common_interface.h"class IB : public ICommonInterface {
public:virtual void callA() = 0;  // B需要调用A的方法
};
4. A类实现(a.h and a.cpp)
// a.h
#pragma once
#include "a_interface.h"class A : public IA {
public:A();void doSomething() override;void callB() override;void setB(IB* b);  // 通过Setter注入B的接口private:IB* m_b;  // 保存B的接口指针
};// a.cpp
#include "a.h"
#include <iostream>A::A() : m_b(nullptr) {}void A::doSomething() {std::cout << "A is doing something!" << std::endl;
}void A::callB() {if (m_b) {m_b->doSomething();  // 调用B的方法}
}void A::setB(IB* b) {m_b = b;
}
5. B类实现(b.h and b.cpp)
// b.h
#pragma once
#include "b_interface.h"class B : public IB {
public:B();void doSomething() override;void callA() override;void setA(IA* a);  // 通过Setter注入A的接口private:IA* m_a;  // 保存A的接口指针
};// b.cpp
#include "b.h"
#include <iostream>B::B() : m_a(nullptr) {}void B::doSomething() {std::cout << "B is doing something!" << std::endl;
}void B::callA() {if (m_a) {m_a->doSomething();  // 调用A的方法}
}void B::setA(IA* a) {m_a = a;
}
6. 依赖管理工厂(service_manager.h and service_manager.cpp)
// service_manager.h
#pragma once
#include "a.h"
#include "b.h"class ServiceManager {
public:static ServiceManager& getInstance();A* getA();B* getB();void setupDependencies();  // 设置A和B的依赖关系private:ServiceManager();A* m_a;B* m_b;
};// service_manager.cpp
#include "service_manager.h"ServiceManager::ServiceManager() : m_a(nullptr), m_b(nullptr) {}ServiceManager& ServiceManager::getInstance() {static ServiceManager instance;return instance;
}A* ServiceManager::getA() {if (!m_a) {m_a = new A();}return m_a;
}B* ServiceManager::getB() {if (!m_b) {m_b = new B();}return m_b;
}void ServiceManager::setupDependencies() {if (m_a && m_b) {m_a->setB(m_b);  // A依赖B的接口m_b->setA(m_a);  // B依赖A的接口}
}
7. 主程序(main.cpp)
#include "service_manager.h"
#include <iostream>int main() {ServiceManager& manager = ServiceManager::getInstance();// 获取实例A* a = manager.getA();B* b = manager.getB();// 设置依赖关系manager.setupDependencies();// 测试双向调用std::cout << "A calls B:" << std::endl;a->callB();  // A调用B的方法std::cout << "\nB calls A:" << std::endl;b->callA();  // B调用A的方法// 释放资源(在实际项目中,应使用智能指针)delete m_a;delete m_b;return 0;
}

这只是一个验证。

同时,根据我的观察:发现城市越发达,代码设计越良好。

同时招聘岗位中描述:靠“设计模式”写出高质量可扩展代码的,都是半吊子。

设计模式是工具。又不是你整体设计的思想依靠。

个人感觉根据实际情况拆分模块,设计层次、整体结构。其次才是考虑如何是否要用到设计模式。设计原则肯定要依据的。

逐步成长,过几年再来看看这篇文章,是否有更好的感悟。

http://www.dtcms.com/a/557332.html

相关文章:

  • 使用mujoco加载模型和控制、以及训练(一)
  • (125页PPT)麦肯锡业务流程规划方法论及流程规划案例(附下载方式)
  • AI学习研究——KIMI对佛教四圣谛深度研究
  • CSS padding(填充)
  • 通信原理(008)——模拟通信和数字通信
  • 山东城建设计院网站公司网站的重要性
  • C#快入教程:Linux安装.NET
  • 《深入浅出统计学》学习笔记(二)
  • 【内存管理】深入理解内存映射(Memory Mapping)与mmap:实现高效零拷贝的DMA缓冲区共享
  • Stm32江科大入门教程--各章节详细笔记---查阅传送门
  • 第六章langchain4j之Tools和prompt
  • 网站开发工作分解结构东营雪亮工程app下载二维码
  • re一下--day6--方法--经验贴
  • 【ubuntu】在Linux系统上安装Microsoft Edge浏览器
  • leetcode 3217. 从链表中移除在数组中存在的节点 中等
  • 滑县网站建设哪家便宜做竞价网站用什么系统好
  • 数学分析简明教程——1.4(未完)
  • element ui下拉框踩坑
  • 【仿RabbitMQ的发布订阅式消息队列】--- 服务端模块
  • C++ vector使用技巧:高效管理动态数据
  • (论文速读)CUT3R:具有持续状态的连续三维感知模型
  • 网站的flash怎么做的hyip网站开发
  • 上海网站建设润滋广州做鞋的网站
  • 互联网大厂Java面试:从Spring Boot到微服务的探索
  • *@AI 辅助模块化开发流程(通用于任意软件)的摘要与架构关系图
  • Python与区块链:如何用Web3.py与以太坊交互
  • TCP Socket(TCP 套接字)和 WebSocket 区别详解
  • 佛山网站建设正规公司深圳旅游网站建设
  • Rust之结构体(Structs):构建自定义数据类型
  • Vue3项目实战:从0到1开发企业级中后台系统(1):颠覆认知!这才是搭建Vue3项目的“正确姿势”