模块互相依赖问题解决的一个记录
背景:
工作以后,为了让自己更好的理解业务代码。
都会将代码抽象分解进行理解。
解耦、可扩展 都是考虑代码设计良好与否的非常重要因素。
之前设计的一个项-目,结合对大佬设计的框-架认识、和自己的经验理解。设计一个模块互相依赖的项目。当时设计的效果,解耦和可扩展效果都还不错。
然后今天问了下大-模型,如何解决模块互相依赖的问题,发现跟大模型设计的思路竟然一致。在此记录一下:
解决方案:接口 + 依赖注入 + 工厂模式
核心思想
- 定义共同接口:A和B都依赖于抽象接口,而不是对方的具体实现
- 使用依赖注入:通过Setter方法注入对方的接口
- 使用工厂管理依赖:通过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;
}这只是一个验证。
同时,根据我的观察:发现城市越发达,代码设计越良好。
同时招聘岗位中描述:靠“设计模式”写出高质量可扩展代码的,都是半吊子。
设计模式是工具。又不是你整体设计的思想依靠。
个人感觉根据实际情况拆分模块,设计层次、整体结构。其次才是考虑如何是否要用到设计模式。设计原则肯定要依据的。
逐步成长,过几年再来看看这篇文章,是否有更好的感悟。
