Thursday, March 12, 2009

Bridge Pattern in C++



When I studied almost all of the Gang of Four Design Patterns in 2005 or 2006, I knew only one language: C++.

Now I am proficient in multiple software languages and my viewpoint about Design Patterns has also matured...

So, here we go.

Here's the source code of the Bridge Pattern, the code is extracted from the presentation.

//Coord.h

#ifndef COORD_H

#define COORD_H


struct Coord {

int x, y;

Coord(int x = 0, int y = 0) : x(x), y(y) {}

};


#endif


// Window.h


#ifndef WINDOW_H

#define WINDOW_H


#include "Coord.h"

#include "WindowImp.h"


class Window {

public:

Window();

virtual ~Window();


void GetWindowImp(int typeOfImplementation); // Attaches implementation

void DrawLine(const Coord& begin, const Coord& end);

void DrawRect(const Coord& topLeft, const Coord& bottomRight);


protected:

WindowImp* imp = nullptr;

};


class IconWindow : public Window {

public:

void DrawBorder(const Coord& topLeft, const Coord& bottomRight);

};


class TransientWindow : public Window {

// Can add specific behavior if needed

};


#endif



// Window.cpp


#include "Window.h"

#include "WindowSystemFactory.h"

#include <iostream>


Window::Window() {}


Window::~Window() {

delete imp;

}


void Window::GetWindowImp(int typeOfImplementation) {

imp = WindowSystemFactory::Instance()->MakeWindowImp(typeOfImplementation);

}


void Window::DrawLine(const Coord& begin, const Coord& end) {

if (imp) imp->DeviceLine(begin, end);

}


void Window::DrawRect(const Coord& topLeft, const Coord& bottomRight) {

if (imp) imp->DeviceRect(topLeft, bottomRight);

}


void IconWindow::DrawBorder(const Coord& topLeft, const Coord& bottomRight) {

DrawRect(topLeft, bottomRight); // Uses bridged implementation

}


// WindowImp.h

#ifndef WINDOWIMP_H

#define WINDOWIMP_H


#include "Coord.h"


class WindowImp {

public:

virtual ~WindowImp() = default;

virtual void DeviceLine(const Coord& begin, const Coord& end) = 0;

virtual void DeviceRect(const Coord& topLeft, const Coord& bottomRight) = 0;

};


class XWindowImp : public WindowImp {

public:

void DeviceLine(const Coord& begin, const Coord& end) override;

void DeviceRect(const Coord& topLeft, const Coord& bottomRight) override;

};


class PMWindowImp : public WindowImp {

public:

void DeviceLine(const Coord& begin, const Coord& end) override;

void DeviceRect(const Coord& topLeft, const Coord& bottomRight) override;

};


#endif


// WindowImp.cpp


#include "WindowImp.h"

#include <iostream>


void XWindowImp::DeviceLine(const Coord&, const Coord&) {

std::cout << "XWindow: Drawing Line\n";

}


void XWindowImp::DeviceRect(const Coord&, const Coord&) {

std::cout << "XWindow: Drawing Rectangle\n";

}


void PMWindowImp::DeviceLine(const Coord&, const Coord&) {

std::cout << "PMWindow: Drawing Line\n";

}


void PMWindowImp::DeviceRect(const Coord&, const Coord&) {

std::cout << "PMWindow: Drawing Rectangle\n";

}



// WindowSystemFactory.h

#ifndef WINDOWSYSTEMFACTORY_H

#define WINDOWSYSTEMFACTORY_H


class WindowImp;


enum WindowImplementation {

XWindowImplementation,

PMWindowImplementation

};


class WindowSystemFactory {

public:

static WindowSystemFactory* Instance();

WindowImp* MakeWindowImp(int type);


private:

WindowSystemFactory() = default;

static WindowSystemFactory* instance;

};


#endif


// WindowSystemFactory.cpp

#include "WindowSystemFactory.h"

#include "WindowImp.h"


WindowSystemFactory* WindowSystemFactory::instance = nullptr;


WindowSystemFactory* WindowSystemFactory::Instance() {

if (!instance) {

instance = new WindowSystemFactory();

}

return instance;

}


WindowImp* WindowSystemFactory::MakeWindowImp(int type) {

if (type == XWindowImplementation) return new XWindowImp();

if (type == PMWindowImplementation) return new PMWindowImp();

return nullptr;

}



//============================================================================

// Name : BridgePattern.cpp

// Author : Som

// Version :

// Copyright : som-itsolutions

// Description : Hello World in C++, Ansi-style

//============================================================================


#include "Window.h"

#include "Coord.h"

#include "WindowSystemFactory.h"

#include <iostream>


int main() {

const Coord pt0(1, 2);

const Coord pt1(7, 8);


// X-based Icon Window

IconWindow* xIcon = new IconWindow();

xIcon->GetWindowImp(XWindowImplementation);

xIcon->DrawBorder(pt0, pt1);


// PM-based Transient Window

TransientWindow* pmTransient = new TransientWindow();

pmTransient->GetWindowImp(PMWindowImplementation);

pmTransient->DrawRect(pt0, pt1);


// PM-based Icon Window

IconWindow* pmIcon = new IconWindow();

pmIcon->GetWindowImp(PMWindowImplementation);

pmIcon->DrawLine(pt0, pt1);


delete xIcon;

delete pmTransient;

delete pmIcon;


return 0;

}

No comments: