首页 > 代码库 > 高内聚与低耦合实现小记
高内聚与低耦合实现小记
总所周知,实际软件开发中要实现高内聚、低耦合的设计原则。c语言和c++不同,c语言面向过程、c++面向对象。
真正的项目中,要对业务升级,原来的业务函数需要保留,要保证老的功能继续维持,不能直接删除,这时候
c语言面向过程,通常使用回调的方法。c++面向对象,要实现高内聚、低耦合,需要使用接口技术。
C语言为例:
软件通常有后台日志的记录功能,用log函数实现,主业务用business函数表示:
void log() { printf("Logging...\n"); }
void business() { while(1) { sleep(1); printf("Deal Business...\n"); log(); } }
int main() { business(); return 0; }
现在需要对后台日志功能进行升级,该如何实现?
一般人的想法是这样:再写一个函数log2,然后business中log改为log2,这样不就可以了?
但是你想想,主业务代码怎能轻易改动?因为一个小小的功能而要改变主要的业务代码,这样不是显得智商很捉急?
换一种思路,使用回调:
#include <stdio.h> #include <unistd.h> void log1() { printf("1 Logging...\n"); } void log2() { printf("2 Logging...\n"); } void business( void (*f)() ) { while(1) { sleep(1); printf("Deal Business...\n"); f(); } } int main() { business(log1); return 0; }
business函数接受一个函数指针,该指针指向的函数没有参数,返回值为void,符合log函数的原型。business中只要f()即可调用相应的函数。
当需要使用log1时,向business传log1、要使用升级后的log2时,传入log2即可。
C++为例:
C++中强调面向对象的思想。
#include <iostream> using namespace std; class Log { public: void log() { cout << "logging..." << endl; } }; class Business { private: Log *l; public: Business(Log *l = NULL) {} void business() { while(1) { sleep(1); cout << "Deal Business..." << endl; l->log(); } } }; int main() { Business b(new Log); b.business(); return 0; }
现在,我们需要对后台日志功能升级,怎么做?有人想到了C++中的重载,在Log类中重载一个函数log2;
也有人想到了继承Log类,覆写log函数等等,但是这几种方法,都需要对Business类中的代码进行变动。如何解决呢?于是C++中的接口技术就派上用处了。
记住,接口强调的是方法,接口里的方法定义为纯虚函数,接口不能实例化、也不需要实例化,需要接口里的功能的类只需要继承该接口即可!下面给出示例:
#include <iostream> using namespace std; class Log { public: virtual void log() = 0;//纯虚函数 }; class Log1 : public Log//继承接口 { public: void log() { cout << "1 logging..." << endl; } }; class Log2 : public Log//继承接口 { public: void log() { cout << "2 logging..." << endl; } }; class Business { public: void business(Log * f)//函数参数只要Log指针,具体传入的是Log1还是Log2的实例,由多态进行实现 { while(1) { sleep(1); cout << "Deal Business..." << endl; f->log(); } } }; int main() { Business b; b.business(new Log2);//会调用Log2类中的log日志函数! return 0; }
此时,对日志业务升级就不会影响business的代码了,只需将不同的日志实例化传入business中即可。
这是一种很棒的设计思想。