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、...
  有纠结,就有解决方法,但很多的时候,就像对待有些书一样,越是纠结,越是解不开。

posted @ 2012-09-05 22:42  走在溪边  阅读(1367)  评论(3)    收藏  举报