关闭

浅谈C++开发中数据结构和算法的分离

发表于:2011-8-24 11:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

  相信每一个在windows下编过程序的人都或多或少地用过位图,大多数人是从网上下载一些成熟完善的DIB类库来使用(例如CxImage、CDIB),少数人有一套自己封装好的DIB类库,方便以后的扩充和使用。(近几年GDI+异军突起,在某些处理方面,如:缩放、旋转、渐变填充等它提供无与伦比的速度和质量,但,如果你想做一个完善的图像处理程序,直接使用它会给架构设计带来困难,你可以用adapter模式封装它后再使用)。

  这时候,如果你需要一些图像处理操作你会怎么办呢?很多没有OO经验的C++程序员(例如一年前的我)可能会这样做:在类中直接添加方法。

  • int FClamp0255 (int nValue) {return max (0, min (0xFF, nValue));} // 饱和到0--255 
  • class FCObjImage  
  • {  
  •  public :  
  • Invert () ;  
  • AdjustRGB (int R, int G, int B) ;  
  • } ;  
  • void FCObjImage::Invert ()  
  • {  
  •  if ((GetHandle() == NULL) || (ColorBits() < 24))  
  • return ;  
  •  int nSpan = ColorBits() / 8 ; // 每象素字节数3, 4 
  •  for (int y=0 ; y < Height() ; y++)  
  •  {  
  • BYTE * pPixel = GetBits (y) ;  
  • for (int x=0 ; x < Width() ; x++, pPixel += nSpan)  
  • {  
  •  pPixel[0] = ~pPixel[0] ;  
  •  pPixel[1] = ~pPixel[1] ;  
  •  pPixel[2] = ~pPixel[2] ;  
  • }  
  •  }  
  • }  
  • void FCObjImage::AdjustRGB (int R, int G, int B)  
  • {  
  •  if ((GetHandle() == NULL) || (ColorBits() < 24))  
  • return ;  
  •  int nSpan = ColorBits() / 8 ; // 每象素字节数3, 4 
  •  for (int y=0 ; y < Height() ; y++)  
  •  {  
  • BYTE * pPixel = GetBits (y) ;  
  • for (int x=0 ; x < Width() ; x++, pPixel += nSpan)  
  • {  
  •  pPixel[0] = FClamp0255 (pPixel[0] + B) ;  
  •  pPixel[1] = FClamp0255 (pPixel[1] + G) ;  
  •  pPixel[2] = FClamp0255 (pPixel[2] + R) ;  
  • }  
  • }  
  • }
  •   这里举了两个例子(分别实现反色,调节RGB值功能),现实中会有大量的此类操作:亮度、对比度、饱和度......现在回想一下,你添加这些方法的步骤是什么,Ooooooooo,RCP(我同事的发明,全称:rapid copy paste^-^),第一步一定是从上面复制一块代码下来,然后改掉其中的接口和处理部分。虽然这里的示范代码很短小,不会连同bug一起复制,但,定时炸弹却又多了一个。有天,你的boss告诉你:我不能忍受长时间的等待,请给我加个进度条.....。你也许会加个全局变量,也许会给每个函数加个参数,但不变的是:你必须修改所有这些处理函数的代码,内心的咒骂并不会使你少改其中的任何一个。而此时,bug已经在旁边伺机而动了...然而苦日子远没熬到头,一个月后,你心血来潮的老板会让你在其中加上区域处理的功能,再一个月后......

      回头重新看看代码?没错,除了红色的代码外,其他地方一摸一样,那能不能把这些算法分离抽出来呢?可能我们马上会想到标准库中qsort和windows中常用的回调方法。好,让我们实作一下:

  • void Pixel_Invert (BYTE * pPixel)  
  • {  
  •  pPixel[0] = ~pPixel[0] ;  
  •  pPixel[1] = ~pPixel[1] ;  
  •  pPixel[2] = ~pPixel[2] ;  
  • }  
  • void FCObjImage::PixelProcess (void(__cdecl*PixelProc)(BYTE * pPixel))  
  • {  
  •  if ((GetHandle() == NULL) || (ColorBits() < 24))  
  • return ;  
  •  int nSpan = ColorBits() / 8 ; // 每象素字节数3, 4 
  •  for (int y=0 ; y < Height() ; y++)  
  •  {  
  • BYTE * pPixel = GetBits (y) ;  
  • for (int x=0 ; x < Width() ; x++, pPixel += nSpan)  
  • {  
  •  PixelProc (pPixel) ;  
  • }  
  •  }  
  • }  
  • void FCObjImage::Invert ()  
  • {  
  •  PixelProcess (Pixel_Invert) ;   
  • }
  • 31/3123>
    《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号