缘起: 在软件开发中,代码解耦是一项至关重要的技术。解耦意味着将相互依赖的模块或组件之间的耦合度降到最低,使得系统更加灵活、可扩展和易于维护。本文将介绍代码解耦的概念和重要性,并提供一些实用的解耦技巧。
+++
码代码就像盖楼!
需要打地基打地基打地基!
需要好框架,做好分层才能分工明确,条理不乱,容易维护!
下面就来举个例子讲一下我单身 24 年悟出的经验吧!
🍕🍔🍟🌭
- 什么是代码耦合? 代码耦合是指模块或组件之间的依赖程度。当一个模块直接依赖于另一个模块的具体实现细节时,就存在高耦合度。高耦合度会导致代码难以修改、测试和重用,增加了系统的复杂性。
- 为什么要解耦代码?
- 灵活性:解耦代码可以使系统更加灵活,当需求变化时,只需修改少量代码而不会对整个系统产生过大的影响。
- 可扩展性:解耦代码可以降低模块之间的依赖关系,使得添加新功能或模块更加容易。
- 可维护性:解耦代码可以使代码结构更清晰,易于理解和维护。同时,解耦也有助于减少错误的传播范围,提高代码的可靠性。
- 可测试性:解耦代码使得单元测试和集成测试更加容易,通过独立测试每个模块,可以更准确地定位和修复问题。
- 解耦技巧:
- 使用接口或抽象类:将具体实现与接口或抽象类分离,其他模块只依赖于接口而不依赖于具体实现。这样,当需要修改实现时,只需修改实现类而无需修改依赖它的模块。
- 事件驱动架构:使用事件机制来解耦模块之间的通信。一个模块触发事件,其他模块根据需要订阅并响应这些事件,从而实现模块之间的解耦。
- 依赖注入:通过将依赖对象从外部传递给模块,使得模块不需要关心对象如何创建和管理。这种方式可以减少模块之间的直接依赖,提高可替换性和可测试性。
- 领域驱动设计(DDD):将代码组织为领域模型,将业务逻辑封装在领域对象中。这种方式可以使代码更加解耦、可读性更好,并且更贴近实际业务需求。
结论: 代码解耦是构建灵活、可维护的软件的关键技术之一。通过使用接口、事件驱动架构、依赖注入和领域驱动设计等技巧,我们可以降低代码耦合度,提高系统的灵活性、可扩展性、可维护性和可测试性。在开发过程中,我们应该始终关注代码解耦,并将其视为提高软件质量和开发效率的重要手段。
来看看例子吧
main.c
/**************************************************** | |
* file : main.c start! | |
****************************************************/ | |
#include "uart.h" | |
#include "processdata.h" | |
/**************************************************** | |
* main() | |
****************************************************/ | |
int main(void){ | |
/* 分离之后,接口可以随意切换,更加具有兼容性!这样写一份代码就可以方便的复用啦!!! | |
processdata: 作为数据的整理 | |
uart: 作为数据的发送接口 */ | |
Processdata_InterfaceInit_t Processdata_InterfaceInit_t; | |
Processdata_InterfaceInit_t.SendData = Uart_Send; | |
Processdata_InterfaceInit_t.RecieveData = Uart_Recieve; | |
Processdata_InterfaceInit(&Processdata_InterfaceInit_t); | |
/* 这样将接口对过去就可以啦! | |
今后想换接口:ethernet/SPI/IIC 等等就直接将函数传入就行啦 */ | |
while(1) | |
{ | |
/* your code */ | |
}; | |
} | |
/**************************************************** | |
* file : main.c end! | |
****************************************************/ |
processdata.h
/**************************************************** | |
* file : processdata.h start! | |
****************************************************/ | |
#ifndef _PROCESSDATA_H | |
#define _PROCESSDATA_H | |
/**************************************************** | |
* Global Type Declaration | |
****************************************************/ | |
typedef (*Processdata_SendType)(uint8_t *data,uint32_t len); | |
typedef (*Processdata_RecieveType)(uint8_t *data,uint32_t *len); | |
typedef struct{ | |
Processdata_SendType SendData; | |
Processdata_RecieveType RecieveData; | |
}Processdata_InterfaceInit_t; | |
/**************************************************** | |
* Global Function Declaration | |
****************************************************/ | |
uint8_t Processdata_InterfaceInit(Processdata_InterfaceInit_t *InterfaceInit_t); | |
#endif /* _PROCESSDATA_H */ | |
/**************************************************** | |
* file : processdata.h end! | |
****************************************************/ |
processdata.c
/**************************************************** | |
* file : processdata.c start! | |
****************************************************/ | |
#include "uart.h" | |
#include "processdata.h" | |
/**************************************************** | |
* Global Variable | |
****************************************************/ | |
bool processdata_InerfaceInit_Flag = false; | |
Processdata_SendType Processdata_SendData = NULL_PTR; | |
Processdata_RecieveType Processdata_RecieveData = NULL_PTR; | |
/**************************************************** | |
* Global Function Implement | |
****************************************************/ | |
/**************************************************** | |
* Processdata_InterfaceInit() | |
****************************************************/ | |
uint8_t Processdata_InterfaceInit(Processdata_InterfaceInit_t *InterfaceInit_t){ | |
do | |
{ | |
/* check */ | |
if((InterfaceInit_t->SendData==NULL_PTR)||\ | |
((InterfaceInit_t->RecieveData==NULL_PTR))) | |
{ | |
continue; | |
} | |
/* init function API */ | |
Processdata_SendData = InterfaceInit_t->SendData; | |
Processdata_RecieveData = InterfaceInit_t->RecieveData; | |
processdata_InerfaceInit_Flag = true; | |
} while ( 0u == 1u ); | |
return 0;/* OK | NOT_OK */ | |
} | |
/**************************************************** | |
* file : processdata.c end! | |
****************************************************/ |
uart.h
/**************************************************** | |
* file : uart.h | |
****************************************************/ | |
#ifndef _UART_H | |
#define _UART_H | |
/**************************************************** | |
* Global Function Declaration | |
****************************************************/ | |
uint8_t Uart_Send(uint8_t *data,uint32_t len); | |
uint8_t Uart_Recieve(uint8_t *data,uint32_t *len); | |
#endif /* _UART_H */ | |
/**************************************************** | |
* file end! | |
****************************************************/ |
uart.c
/**************************************************** | |
* file : uart.c start! | |
****************************************************/ | |
/**************************************************** | |
* Global Function Implement | |
****************************************************/ | |
/**************************************************** | |
* Uart_Send() | |
****************************************************/ | |
uint8_t Uart_Send(uint8_t *data,uint32_t len){ | |
/* Uart Driver */ | |
return 0;/* OK | NOT_OK */ | |
} | |
/**************************************************** | |
* Uart_Recieve() | |
****************************************************/ | |
uint8_t Uart_Recieve(uint8_t *data,uint32_t *len){ | |
/* Uart Driver */ | |
return 0;/* OK | NOT_OK */ | |
} | |
/**************************************************** | |
* file : uart.c end! | |
****************************************************/ |
学会了嘛😜
谢谢可爱的你能看到最后呢!
爱你呀😍