C++的整理箱
编程总是与纠结分不开,下面的纠结与程序的可读性有关。
1、纠结:
函数写着写着太长了,要分解吧?问题来了,分解出来的函数不太好找地方放了,放在类里头,污染了类,放在全局的空间里,又污染了整个环境。而且这些函数其实也就原来这个函数调用,总是要放在边上吧。
再看看类,刚开始时就几个函数,清清楚楚,写着写着就多出来很多私有函数,阅读代码时,就有点找不到主次了。
2、整理箱:
这个时候,无论是类还是函数,都需要一个整理箱,为这些多出来的函数找一个合适的场所,至于整理箱在哪里,看看下面的例子就清楚了。
3、一个例子:
class lexer { public: int insymbol(); tchar nextch(); private: int eatcomment(); int eatnumber(); int eatstring(); int eatoperator(); private: .... }
这是一个比较常见的例子,lexer类重要的函数是insymbol,nextch,eat开头的函数其实都服务于insymbol。
4、类整理箱:
在以上lexer类中,eat开头的函数,使得本身类的结构变得不清晰,增加了阅读代码的难度,在这里,我们增加一个类整理箱,整理这些函数。
增加整理箱后, lexer的声明代码如下,是否比原来简洁了:
class lexer { public: int insymbol(); tchar nextch(); private: struct __; //整理箱 private: .... };
现在再在lexer.cpp增加实现部分,代码如下:
#include "lexer.h" struct lexer::__ { static int eatcomment(lexer* plexer) { ... } static int eatnumber(lexer* plexer) { ... } static int eatstring(lexer* plexer) { ... } static int eatoperator(lexer* plexer) { ... } }; lexer::insymbol { .... __::eatnumber(this); //调用了整理箱函数 .... };
现在这些函数都放进了整理箱,即没有对类污染,也没有对全局环境有污染,达到了整理的目的。
5、函数整理箱:
在上面,我们eat这些函数放进了类的整理箱,下面我们找一个更适合它们呆的地方,既然它们都服务于insymbol,我们就内部解决,把整理箱放在函数里面。
先把整理箱从类中移出,现在lexer的声明代码如下:
class lexer { public: int insymbol(); tchar nextch(); private: .... };
然后把整理放进insymbol函数。
#include "lexer.h" lexer::insymbol { struct __ { static int eatcomment(lexer* plexer) { ... } static int eatnumber(lexer* plexer) { ... } static int eatstring(lexer* plexer) { ... } static int eatoperator(lexer* plexer) { ... } }; .... __::eatnumber(this); //调用了整理箱函数 .... };
现在我们把辅助函数放进了函数整理箱,同样对类和全局环境都没有污染。阅读代码时,先把整理箱关上,要细究时,也不需要东找西找,直接打开就可以了。如对函数有调整,整理起来也顺手。
下面的代码,对整理箱做了一些包装,看起来好看一些,只是箱子一下子关不起来了。
#include "lexer.h" #define BOX_HEAD struct __ { #define BOX_TAIL }; lexer::insymbol { BOX_HEAD static int eatcomment(lexer* plexer) { ... } static int eatnumber(lexer* plexer) { ... } static int eatstring(lexer* plexer) { ... } static int eatoperator(lexer* plexer) { ... } BOX_TAIL .... __::eatnumber(this); //调用了整理箱函数 .... };
6、...
有纠结,就有解决方法,但很多的时候,就像对待有些书一样,越是纠结,越是解不开。
浙公网安备 33010602011771号