运用设计模式设计MIME编码类 -- 兼谈Template Method和Strategy模式的区别

豆豆网   技术应用频道   2007年03月16日    社区交流

本文详细介绍运用设计模式设计MIME编码类 -- 兼谈Template Method和Strategy模式的区别

  · Source Buffer仍然支持unsigned char *和CString这 2种类型,而Target Buffer由CMimeString本身来管理不必用户操心了。

  · 但具体应用不是对二进制对象进行编码时,可以不用foo( s.GetBuf() )而直接用foo( s ),因为operator LPCTSTR() const;自动负责类型转换。

  · 直接从构造函数传递Source Buffer的信息,使得接口更为精简。

  当具体使用CMimeString时,大概象这样:CString  buf("sadfsdfsdf");
CMimeString mime(CMimeString::ENCODING, buf);
MessageBox( s );
看来易使用性不错,下面要着重解决易扩展性了。CMimeString的实现部分会象这样:class CMimeString
{
protected:
  unsigned char * mBuf;
  int mBufLen;
  virtual void Encode( unsigned char * inBuf, int inBufLen );
  virtual void Decode( unsigned char * inBuf, int inBufLen );
};
其中的两个虚函数是专门为易扩展性准备的,要实现新的MIME编码算法,只需要从CMimeString继承一个子类:class CBase64String : public CMimeString
{
protected:
  virtual void Encode( unsigned char * inBuf, int inBufLen );
  virtual void Decode( unsigned char * inBuf, int inBufLen );
};
类图如下:

  

  这两个虚函数是在哪里被调用的呢?在基类的构造函数中。CMimeString::CMimeString(WHICHTYPE inType, CString & inStr)
{
  mBuf = 0;
  mBufLen = 0;
  if( inType == ENCODING )
  {
    Encode((unsigned char *)(inStr.operator LPCTSTR()), inStr.GetLength());
  }
  else if( inType == DECODING )
  {
    Decode((unsigned char *)(inStr.operator LPCTSTR()), inStr.GetLength());
  }
}
看上去是很不错的Template Method模式的运用,但是有问题——因为“在构造函数中调用虚函数”并无多态特性!CBase64String::CBase64String(PROCESSTYPE inType, CString inStr)
{
  OnlyInitSelf();
}
之后CString  buf("sadfsdfsdf");
CBase64String base64(CMimeString::ENCODING, buf);
MessageBox( base64 );
是不对的,仍然是基类的CMimeString::Encode()被调用了,而且OnlyInitSelf()在Encode()被调用之后才被调到。

作者:温昱    责编:豆豆技术应用

正在加载评论...