Struggling to understand Bridge pattern benefits

  • Thread starter ghost_of_rooney
  • Start date
G

ghost_of_rooney

Maybe my example isn't a good candidate for Bridge, or maybe I'm
applying Bridge incorrectly, but I don't see the benefit of the
pattern here. If I eliminated the Bridge and extended the shape
hierarchy to implement all combinations of shape/api, the number of
classes would be the same and the factory could still be used to
create the correct one. The client would still only care about the
shape interface. Seems like the proliferation of classes is simply
pushed to the implemetation hierarchy.

What am I missing?

#include <iostream>

class shape_impl {
public:
virtual ~shape_impl() {}
virtual void draw() = 0;
};

class opengl_circle : public shape_impl {
public:
virtual void draw() { std::cout << "opengl circle" <<
std::endl; }
};

class opengl_quad : public shape_impl {
public:
virtual void draw() { std::cout << "opengl quad" << std::endl; }
};

class directx_circle : public shape_impl {
public:
virtual void draw() { std::cout << "directx circle" <<
std::endl; }
};

class directx_quad : public shape_impl {
public:
virtual void draw() { std::cout << "directx quad" << std::endl; }
};

class raw_circle : public shape_impl {
public:
virtual void draw() { std::cout << "raw circle" << std::endl; }
};

class raw_quad : public shape_impl {
public:
virtual void draw() { std::cout << "raw quad" << std::endl; }
};

class shape {
protected:
shape_impl *impl;
public:
shape(shape_impl * i) : impl(i) {}
virtual ~shape() {}
virtual void draw() = 0;
};

class circle : public shape {
public:
circle(shape_impl * i) : shape(i) {}
virtual void draw() { impl->draw(); }
};

class quad : public shape {
public:
quad(shape_impl * i) : shape(i) {}
virtual void draw() { impl->draw(); }
};

class shape_factory {
static const int OPENGL;
static const int DIRECTX;
static const int RAW;
static shape_factory * instance;
int graphics_api;
public:
static shape_factory * get_instance(int api);
shape_factory(int api) {
graphics_api = (api == 1 || api == 2) ? api : RAW;
}
shape * create_circle() {
if (graphics_api == OPENGL) {
return new circle(new opengl_circle);
} else if (graphics_api == DIRECTX) {
return new circle(new directx_circle);
} else { // Raw mode
return new circle(new raw_circle);
}
}
shape * create_quad() {
if (graphics_api == OPENGL) {
return new quad(new opengl_quad);
} else if (graphics_api == DIRECTX) {
return new quad(new directx_quad);
} else { // Raw mode
return new quad(new raw_quad);
}
}
};

const int shape_factory::OPENGL = 1;
const int shape_factory::DIRECTX = 2;
const int shape_factory::RAW = 3;
shape_factory * shape_factory::instance = 0;
shape_factory * shape_factory::get_instance(int api) {
if (instance == 0) {
instance = new shape_factory(api);
}

return instance;
}

int main(int argc, char *argv[]) {
if (argc > 1) {
shape_factory *sf =
shape_factory::get_instance(atoi(argv[1]));

shape * c = sf->create_circle();
c->draw();
shape * q = sf->create_quad();
q->draw();
} else {
std::cout << "Usage: bridge [1 | 2 | 3]" << std::endl;
}

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top