这个修改看似简单,但是实际上,却使Log.c解除了对cfgfile.c的依赖。也就是说,Log这个模块不再依赖于配置文件。由于配置文件依赖于XML,那么Log也不再依赖于XML.链式依赖关系已经断裂,所以Log.c这个模块基本上可以重用了。从可以看出,在编码设计阶段的稍有不注意,都会给后继开发带来巨大的麻烦。不可不小心谨慎的进行设计。
原则1: 模块的功能要单一。在模块中调用其他模块的时,要慎之又慎。只有必要时才这样做。
二 头文件包含其他头文件
此外,如果Log.c中还#include了def.h,那注定不能被轻易的“拷贝”。这处于工程开发阶段的一个方便的考虑:假设我把所有的头文件、宏定义、或者函数声明都包含在一个叫做 def.h的头文件中。那么,我编写.c文件的时候会非常方便,一般只要#include “def.h”就可以了,不用担心任何缺少头文件之类的问题。但是事实上,在代码重用的时候,最害怕碰到的,就是”def.h”之类的头文件。因为,打开这样的头文件之后,常常看到的是下面的情况:
#include “cfgfile.h”换句话说,如果我要在我的工程中使用这个头文件,我必须得拷贝“cfgfile.h”,”genutl.h”,”mysocket.h”这三个文件,而且这必须在cfgfile.h等几个文件中,没有再度#include别的头文件的情况。一般的说,我们现在代码的现状,都是很轻易的在头文件中包含其他的头文件。最终的结果,发现我们包含这个头文件是不可能的。因为需要拷贝的文件太多了。
#include “genutl.h”
#include “mysocket.h”
……
原则2:在头文件中包含其他的头文件往往是不必要的,是应该禁止的。只有万不得已的情况,才能这样做。
有时你会觉得,原则2是荒唐的。似乎违犯了一贯编程的原则。但是实际上,几乎99%的情况都可以证明,在头文件中包含其他的头文件,是没有必要的。举一个例子如下:我编写了一个类的头文件class_a.h:
class MyClassA这时候,似乎#include “class_b.h”是唯一的选择。否则MyClassB m_bObject这一句无法通过编译。但是实际上,在这里定义MyClassB的对象作为MyClassA的一个成员是不对的。后面会重点讲述:为何使用对象的指针总是比使用对象更好。看下面的代码:
{
public:
…
private:
MyClassB m_bObject;
};
class MyClassB;
class MyClassA
{
public:
…
private:
MyClassB *m_bObject;
};