如果我继续编写更多的代码,那么有时候我将很难组织代码。
这是您的问题:组织正确,样式应该更容易流动。
不要等待组织代码:随时随地组织代码。尽管该语言无法满足您的要求,但仍应将代码组织成具有低耦合度和高内聚性的模块。
这些模块自然会提供一个名称空间。缩写模块名称(如果很长),并在模块名称前加上函数名称,以避免冲突。
在单个标识符的级别上,这些标识符大致按主观顺序递增:
- 选择一个约定并坚持下去
- 例如,
function_like_this(struct TypeLikeThis variable)
很常见
绝对避免使用匈牙利表示法(对不起,JNL)
避免使用指针typedef,除非它们是真正不透明的cookie类型-它们只会使事情变得混乱
struct Type *ok;
typedef struct Type *TypePtr;
TypePtr yuck;
不透明的Cookie类型是什么意思?我的意思是必须在模块(或库或其他任何东西)中使用的东西必须传递给客户端代码,但该客户端代码不能直接使用。它只是将其传递回库。
例如,数据库库可能会公开类似
/* Lots of buffering, IPC and metadata magic held in here.
No, you don't get to look inside. */
struct DBContextT;
/* In fact, you only ever get a pointer, so let's give it a nice name */
typedef struct DBContexT *DBContext;
DBContext db_allocate_context(/*maybe some optional flags?*/);
void db_release_context(DBContext);
int db_connect(DBContext, const char *connect);
int db_disconnect(DBContext);
int db_execute(DBContext, const char *sql);
现在,上下文对于客户端代码是不透明的,因为您无法查看内部。您只需将其传递回库。诸如此类的东西FILE
也是不透明的,并且整数文件描述符也是cookie,但也不是不透明的。
设计注意事项
我在上面使用了“ 低耦合和高内聚力 ”一词,没有任何解释,对此我感到很不好。您可以搜索它,并且可能会找到一些不错的结果,但是我将尝试简要地解决它(同样,我可以写一篇文章,但会尝试不这样做)。
上面概述的数据库库显示出较低的耦合度,因为它向外界公开了一个小的接口。通过隐藏其实现细节(部分使用不透明的cookie技巧),它可以防止客户端代码依赖于那些细节。
想象一下,而不是不透明的cookie,我们声明上下文结构,以便其内容可见,其中包括用于与数据库的TCP连接的套接字文件描述符。如果我们随后在数据库运行在同一台机器上时更改实现以支持使用共享内存段,则需要重新编译客户端,而不仅仅是重新链接。更糟糕的是,客户端可能已经开始使用文件描述符,例如调用setsockopt
更改默认缓冲区大小,现在它也需要更改代码。所有这些详细信息都应在可行的情况下隐藏在我们的模块内部,这样可以降低模块之间的耦合。
该示例还显示出很高的凝聚力,因为模块中的所有方法都与同一任务(数据库访问)有关。这意味着只有需要了解实现细节(即cookie的内容)的代码才可以实际访问它们,从而简化了调试。
您还可以看到,只需关注一个问题,就可以轻松选择前缀来将这些功能分组在一起。
现在,说这个例子很好是很容易的(特别是因为它还不完整),但是并不能立即为您提供帮助。诀窍是在编写和扩展代码时观察执行相似操作或在相同类型上运行的函数(可能是其自身模块的候选对象),以及执行许多其他未完成的单独操作的函数。确实相关,并且可能是拆分的候选者。