4.1.3 Strategy Pattern

The Strategy pattern is a kind of behavioral pattern that provides a series of alternative approaches at runtime. At the same time, the client could change the strategy flexibly between these strategies depending on their choice (Gamma 1994).

Figure 4.1.5 illustrates the structure of this pattern. In my project, this pattern is used to represent the different kinds of images depending on their own channels (cf. Figure 4.1.6). The ImageChannel class represents the abstract strategy class, and these three concrete channel classes are concrete image channel classes. The ChannelContext class has a reference of the ImageChannel. The code segments in A, B, C and D depict the implementation of the strategy pattern and the transform channel in my project. The reason why I use channel transform is to display an image with QImage rather than Mat. For each type of image, the transform approach is different.

Thus, the channel divides images into different kinds according to their color patterns with a color begin used to represent each sort of image.

Figure 4.1.5: The structure of strategy pattern (Vanderjoe 2016)
Figure 4.1.6: The implementation of strategy pattern
class ChannelContext
{
private:
  ImageChannel* img_channel;
public:
  ChannelContext (ImageChannel* imc);
  ImageChannel *getImg_channel() const;
  void setImg_channel(ImageChannel *value);
};
Code Segment A: ChannelContext Interface Definition
void ThreeChannel::QImageTransfer(Mat mat)
{
  const uchar* pSrc = (const uchar*)mat.data;
  QImage image (pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
  this->img = image.rgbSwapped();
}
Code Segment B: ThreeChannel Image Transformation implementation
void FourChannel::QImageTransfer(Mat mat)
{
    QImage imgs(static_cast<uchar*>(mat.data), mat.cols, mat.rows, OImage::Format_ARGB32);
    this->img = imgs
}
Code Segment C: FourChannel Image Transformation implementation
void OneChannel::QImageTransfer(Mat mat)
{
  imshow("000",mat);
  QImage img(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
  img.setColorCount(256);

  for (int i=0;i<256;i++)
  {
    img.setColor(i, qRgb(i,i,i));
  }
  uchar* psr = mat.data;
  for (int row=0;row<mat.rows;row++)
  {
    uchar* pdest = img.scanLine(row);
    memcpy(pdest, psr, mat.cols);
    psr += mat.step;
  }
  this->img = img;
}

Code Segment D: OneChannel Image Transformation implementation

Overall, this pattern avoiding me having to use several if-else branches. However, this is only suitable for conditions where the client knows all the actions in advance.