Bridge design pattern is something which is very confusing and GOF does not do justice with beginners in the definition.
I was asked in my current organisation to add one more dimension to our class and use Bridge pattern for it, knowing nothing about it I went through some blogs and have implemented the same for our code. OFC I cannot paste the code base here so providing some minimal similar example as that in my code base.
Say there is a video class containing 2 dimension: VideoType
and VideoProcessor
. These 2 dimensions are independent of each other. And without using the bridge design pattern, this is what the code would have looked like.
#include <iostream>
class Video
{
protected:
std::string filename;
public:
Video(const std::string &filename)
{
this->filename = filename;
}
virtual void ProcessVideo() = 0;
virtual void Play() = 0;
};
class NetflixVideoHD : public Video
{
public:
NetflixVideoHD(const std::string &filename) : Video(filename) { }
void Play()
{
std::cout<<"Playing HD Netflix video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing HD Netflix video : " << filename << std::endl;
}
};
class NetflixVideo4KHD : public Video
{
public:
NetflixVideo4KHD(const std::string &filename) : Video(filename) { }
void Play()
{
std::cout<<"Playing 4KHD Netflix video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing 4KHD Netflix video : " << filename << std::endl;
}
};
class YouTubeHD : public Video
{
public:
YouTubeHD(const std::string &filename) : Video(filename) { }
void Play()
{
std::cout<<"Playing HD YouTube video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing HD YouTube video : " << filename << std::endl;
}
};
class YouTube4K : public Video
{
public:
YouTube4K(const std::string &filename) : Video(filename) { }
void Play()
{
std::cout<<"Playing 4K YouTube video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing 4K YouTube video : " << filename << std::endl;
}
};
int main()
{
Video *nethd = new NetflixVideoHD("Video.mp4");
Video *net4khd = new NetflixVideo4KHD("Video.mp4");
Video *ythd = new YouTubeHD("Video.mp4");
Video *yt4Khd = new YouTube4K("Video.mp4");
nethd->ProcessVideo();
nethd->Play();
net4khd->ProcessVideo();
net4khd->Play();
ythd->ProcessVideo();
ythd->Play();
yt4Khd->ProcessVideo();
yt4Khd->Play();
delete nethd;
delete net4khd;
delete ythd;
delete yt4Khd;
}
Now after converting the same to bridge design pattern by converting one base class to abstract and other to interface, this is how the new code looks like.
#include <iostream>
/* One dimension converted to Interface */
class VideoProcessorInterface
{
public:
virtual void ProcessVideo(const std::string &filename) = 0;
};
class VideoProcessorHD : public VideoProcessorInterface
{
public:
void ProcessVideo(const std::string &filename)
{
std::cout<<"Processing HD video : " << filename << std::endl;
}
};
class VideoProcessor4KHD : public VideoProcessorInterface
{
public:
void ProcessVideo(const std::string &filename)
{
std::cout<<"Processing 4K video : " << filename << std::endl;
}
};
/* Other dimesnion used as abstract class */
class Video
{
protected:
std::string filename;
VideoProcessorInterface *videoProcessor;
public:
Video(const std::string &filename, VideoProcessorInterface *videoProcessor)
{
this->filename = filename;
this->videoProcessor = videoProcessor;
}
virtual void ProcessVideo() = 0;
virtual void Play() = 0;
};
class NetflixVideo : public Video
{
public:
NetflixVideo(const std::string &filename, VideoProcessorInterface *videoProcessor) : Video(filename, videoProcessor) { }
void Play()
{
std::cout<<"Playing Netflix video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing Netflix video in below quality " << filename << std::endl;
videoProcessor->ProcessVideo(filename);
}
};
class YouTube : public Video
{
public:
YouTube(const std::string &filename, VideoProcessorInterface *videoProcessor) : Video(filename, videoProcessor) { }
void Play()
{
std::cout<<"Playing YouTube video : " << filename << std::endl;
}
void ProcessVideo()
{
std::cout<<"Processing YouTube video in below quality " << filename << std::endl;
videoProcessor->ProcessVideo(filename);
}
};
int main()
{
VideoProcessorHD hdVideoProcessor;
VideoProcessor4KHD f4KVideoProcessor;
Video *nethd = new NetflixVideo("Video.mp4", &hdVideoProcessor);
Video *net4khd = new NetflixVideo("Video.mp4", &f4KVideoProcessor);
Video *ythd = new YouTube("Video.mp4", &hdVideoProcessor);
Video *yt4Khd = new YouTube("Video.mp4", &f4KVideoProcessor);
nethd->ProcessVideo();
nethd->Play();
net4khd->ProcessVideo();
net4khd->Play();
ythd->ProcessVideo();
ythd->Play();
yt4Khd->ProcessVideo();
yt4Khd->Play();
delete nethd;
delete net4khd;
delete ythd;
delete yt4Khd;
}
I just wanted to know whether the above conversion strategy follows bridge design pattern. And what are the issues with it.