I am studying an example of a Bridge Pattern from "Designed Patterns Explained".
The example I am looking at is Example 10.3 which can be found at
http://www.netobjectives.com/resources/books/design-patterns-explained/cpp-code-examples/chapter10#10-3
The specific confusion I have is with the Shape class and its derived classes.
#pragma once
#include "Drawing.h"
class Shape
{
public:
Shape(Drawing *aDrawing);
virtual void draw()= 0;
protected:
Drawing *myDrawing;
void drawLine( double, double, double, double);
void drawCircle( double, double, double);
public:
~Shape(void);
};
In the Circle class we have
#pragma once
#include "Shape.h"
class Circle : public Shape
{
public:
Circle(Drawing*, double, double, double);
virtual void draw();
virtual void drawCircle(double, double, double)=0;
public:
~Circle(void);
protected:
double _x, _y, _r;
};
So the question I have is:
why can drawCircle be pure virtual in the inherited class given that the method is in fact implemented in the base class?
Imagine you're building a module to draw shapes using different API's (windows GDI, some smartphone API, OpenGL, anything). Having a typical hierarchy abstract Shape <--- concrete Circle and abstract Shape <--- concrete Rectangle you would have to recompile and redeploy Circle and Rectangle each time you add a new framework and each time something changes in the existing framework. Such changes may even involve modifying the constructors of these classes so users of your module would have to also change their code.
Example: you have a working first version of your module, with the following interface for Circle:
class Circle : public Shape
{
public:
Circle(int x, int y, int radius);
void draw(...);
};
Then, it happens that optimization reasons for one of the platforms force you to know the DPI resolution of the current platform in advance (before actually drawing the circle). So, you would have to change the constructor:
class Circle : public Shape
{
public:
Circle(int x, int y, int radius, int dpi);
void draw(...);
};
and clients of your code would have to recompile their applications. There would be of course some hacks possible to avoid this (like introducing CircleWithDpi), but they would lead to a highly coupled and hard to maintain code. If you use the bridge pattern you can have your clear design left intact and still express your domain (in general, concept of a "circle" shouldn't know anything about a thing called "dpi resolution").
So having:
class Circle : public Shape
{
public:
Circle(int x, int y, int radius);
virtual void draw(...) = 0;
};
and
class CircleImpl : public Circle
{
public:
CircleImpl(int x, int y, int radius, int dpi);
//perform some calculations before drawing for optimization
void draw(...);
//draw using appropriate API
};
and
class ShapeFactory
{
public:
virtual Circle* CreateCircle(int x, int y, int radius) = 0;
};
Of course you would have many CircleImpls - each for different platform your module supports (so, CircleImplGDI, CircleImplTk, CircleImplOpenGL etc.).
In the implementation of the ShapeFactory you'd create a particular CircleImpl appropriately and the client of your module doesn't have to know anything about it. This example is the simplified version of the one you've given link to. Note that now, when one of possible CircleImpls is used as Circle no abstract classes are being instantiated, so this should also clear out your issue about abstract derived class.
The main idea behind this pattern is to have two levels of abstraction: Shape is an abstract geometrical concept, Circle and Rectangle are more concrete than the Shape but in the context of many technical possibilities for drawing them they are still quite abstract. Concrete representations of particular shapes exist when you know the context: for example - drawing on a raster or using vector graphics.
Another level of abstraction gives you possibility to defer some more decisions about your code - at first we defer the decision about what shapes we have. Then, having Circle and Rectangle we defer the decision about how to draw them. And deferred decisions give us decoupled, flexible code (as demonstrated with the "added DPI" example).
Pure virtual methods are allowed in any class, as long as you don't try to create an instance of that class.
Related
Let say that I have a big class Circle with a lot of members and functions. To proceed a large amount of data I decided to create class PotentialCirlce (with only 3 members - x, y, r), do most of preprocessing based on PotentialCirlce and in the last stage create objects Circle.
a) is it correct approach? do It influence on performance or rather should I use only Circle.
It seems to me that I can use inheritance:
class potentialCircle {
protected:
point_t center;
unsigned int radius;
public:
potentialCircle(int a, int b, unsigned int r) : center{ point_t(a,b) }, radius{ r } {}
potentialCircle() = delete;
potentialCircle(const potentialCircle&) = default;
potentialCircle(potentialCircle&&) = default;
potentialCircle& operator=(const potentialCircle&) = default;
potentialCircle& operator=(potentialCircle&&) = default;
virtual ~potentialCircle() = default;
};
class Circle : public potentialCircle {
// members detected based on Hough Circle Transform
//point_t center; // coordinates of center point
point_t alternative_center; // needed when center is out of frame
//unsigned int radius; // radius
// members calculated based on Flood Fill algorithm (more realistic)
unsigned int area = 0;
float diameter = 0;
float perimeter = 0;
....
};
b) where should I put method which needs to compare two difference objects? one object of type Circle and one of PotentialCirle?
currently, I have defined below function as part of Circle
bool Circle::is_greater(const std::pair<potentialCircle, int>& point_pair) const;
but I don't have access to protected data members of potentialCircle, although Circle is inheriting from potentialCircle.
Maybe I should defined is_greater() as part of namepsace and make it a friend to Circle and potentialCircle.
Do you have better idea?
There are not really a good approach to compare objects of different types as it make little sense in practice. What would be the purpose of such comparisons.
Now even if you have a single class, if the ordering is not intransic to the type, it would be better to use an external class for sorting.
class CircleDiameterLess
{
public:
bool operator()(const Circle &lhs, const Circle &rhs)
{
return lhs.diameter < rhs.diameter;
}
};
That way, you can have multiple ways to sort data and it play nice with STL.
Another problem with your code if that it make little sense to have a class circle with a diameter that derives from a class potentialCircle with a radius. Your code will be hard to maintain because it is hard to understand.
You want to store either the diameter or the radius and compute the other one.
unsigned int get_diameter() const { return radius * 2; }
Member like alternative_center make no sense. A circle has only one center. If your class does not respect basic expectations, it will make the code hard to maintain as nobody would known that a circle has 2 centers including you in 3 months!
In a case like yours, it make make sense to add public accessors.
class potentialCircle
{
public:
unsigned int get_radius() const { return radius; }
....
};
That way, you can still make data private (or sometime protected) while having read only access to it. That way, you can write you comparison function as you wish. And in practice, if you have a class that represent a circle, you usually want at least being able to get basic properties like radius, aread, bounding rectangle by the way of a function.
Another thing is that public derivation as your (from potentialCircle) would only make senses if you have other classes that derives from it. However, if this is the case, then how would you compare the other kind of circles?
Notes:
With C++ 20, three way comparison would be even better.
I think the problem is quite basic and there was the same Question for sure somewhere here but i wasn't able to find.
So here is the Problem. Top has access to MyCircle and calls the SetSize function. But MyCircle has no access to MyRect.
I am able to access MyRect if i am providing a pointer to MyRect within the Constructor of MyCircle, but i think there should be another way. Maybe i just got it wrong at all :( Thanks for your help.
in the
class Top{
public:
Rect myRect;
Circle myCircle;
void Run();
};
class Rect{
public:
int size;
};
class Circle{
public:
int size;
void SetSize(int buffer);
};
void Circle::SetSize(int buffer){
myRect.Size = buffer;
}
void Top:Run(){
myCircle.SetSize(10);
}
Don't pass a rectangle to a circle class, the circle should have no knowledge about the rectangle (or vice versa).
Instead make a function in Top using both the circle and rect and act on that.
I don't know exactly what you want to do, but suppose you want to set the sizes equally. Than make e.g. a SetSize method in Top setting the sizes for both the circle and rectangle:
e.g.
class Top{
public:
Rect myRect;
Circle myCircle;
void Run();
void SetSize(int size)
}
where SetSize is implemented as:
myRect.SetSize(size);
myCircle.size = size;
It's always better to put code handling multiple derived objects in the base class instead of in one of the children. If there will be too much (or unrelated) functionality in the base class, create a different class (like SizeHandler).
btw, it's better not to use public properties but always get/set methods.
I have created 2 classes.One is called Shape and its a virtual class.The other one is called Circle(I intend to create more of them like : triangle,square ....).I want to find circle area of the object,but that isnt important.Here is my problem.When I want to create an object like this :
vector<Shape *> mStack;
Shape *newShape = NULL;
newShape = new Circle(10.6);
mStack.push_back(newShape);
I can create it in the main file without problems.But when I try to create a function of it inside the "Shape" class..like this:
void Shape::Create()
{
Shape *newShape = NULL;
newShape = new Circle(10.6);
mStack.push_back(newShape);
}
I get following error: syntax error: identifier 'Circle'
... Here are my classes.
#pragma once
#include <vector>
using namespace std;
class Shape
{
private:
vector<Shape *> mStack;
public:
Shape();
~Shape(void);
virtual double Circle_area() = 0;
};
*********************************************************
#pragma once
#include "Shape.h"
class Circle : public Shape
{
private:
double m_r;
public:
Circle();
Circle(double r);
~Circle(void);
double Create();
double Circle_area();
};
Where is the problem here? How can I create an object inside the parent class? I hope you understand what I am trying to say. Thanks for the help.
Your Design is now improper. By proper design, your shape could act as an abstract class or base class for the real circles or rectangles. If then your design will be.,
And in main() you could maintain, a list of shapes vector<Shape *> mStack; which will not create problem. But you must not create circle or rectangle in shape. Thats a wrong design in my point of view.
Your base class is more than weird.
a base class should have virtual destructor
having a collection of itself is suspect for overreaching (you might have a CompositeShape down the hierarchy...)
It has a function named as a subclass. (could be shape_area() or just area())
Your implementation trouble is coming from this too: if the collection is not in shape, then create would not want to fill it, and problem gone.
From the provided info it's not clear where the content of create should go, may be the app, or may be some specific complex shape -- those could simply include all the required headers.
look at this code
#include<iostream>
using namespace std;
//Shape is an Interface Class. No data and everything pure virtual
class Shape {
public:
virtual void Area(int length, int breadth) = 0;
virtual void Perimeter(int length, int breadth) = 0;
//Note, no data
};
//Derived class - Inherits Shape as Public
class Rectangle : public Shape {
public:
void Area(int length, int breadth);
void Perimeter(int length, int breadth);
private:
int someData;
};
//Derived class - Inherits Shape as Public
class Triangle : public Shape {
public:
void Area(int length, int breadth);
void Perimeter(int length, int breadth);
private:
int someData;
};
int main()
{
Rectangle r;
Triangle t;
cout<<"\n\n";
r.Area(3,4);
r.Perimeter(3,4);
t.Area(3,4);
t.Perimeter(3,4);
cout<<"\n\n";
return 0;
}
void Rectangle::Area(int length, int breadth)
{
cout<<"\nThe Area of Rectangle for length = "<<length<<" and\
breadth = "<<breadth<<" is "<<(length * breadth)<<endl;
}
void Rectangle::Perimeter(int length, int breadth)
{
cout<<"\nThe Perimeter of Rectangle for length = "<<length<<" and\
breadth = "<<breadth<<" is "<<2 * (length + breadth)<<endl;
}
void Triangle::Area(int length, int breadth)
{
cout<<"\nThe Area of Triangle for length = "<<length<<" and\
breadth = "<<breadth<<" is "<<(length * breadth)/2<<endl;
}
void Triangle::Perimeter(int length, int breadth)
{
cout<<"\nThe Perimeter of Triangle for length = "<<length<<" and\
breadth = "<<breadth<<" is "<<(length * breadth)/3<<endl;
}
I use interface in the code , but my question is what i should use it and what is the benefits from it , no performance , no real needed it , why i should i use it ( the interfaces ) . what is the point to use it , an you explain it please .
and thank you !
Abstract interfaces separate the interface from the implementation. Just as pimpl idiom it
decreases compilation time, and
lets you change the implementation without breaking the ABI.
Both are important advantages in large programs.
An interface could be used to have, say, a vector of different Shape objects. Otherwise you couldn't have a collection that mixes triangles and rectangles for example. Or another class could have a Shape member, which could then either be a triangle or rectangle. These are just some examples.
Edit:
Let me give a concrete example. Say you have an interface called Car. Imagine you want to have a class Garage that has room for a single Car. You've implemented different types of cars, that all use the Car interface. Then the Garage class could be something like:
class Garage {
public:
Car getCar(); // returns _theCar
private:
Car _theCar:
}
A common mistake when programming C++ (and other object oriented languages) is to use inheritance too much. Interfaces is inheritance done right. The reason is that the strength of interfaces is to be able to handle objects of different type in another system as if they were the same type. Triangle and Circle can both be Shapes for instance and can be passed to a graphics engine for drawing on the screen.
The reason interfaces are 'better' than inheritance that also includes inherited functionality is that it quickly becomes very hard to understand what a class really does, to debug it and verify that the internal state of the objects cannot be destroyed by using the external methods.
The need for this type of structure where you use interfaces more than sporadically is hard to motivate in a small example, but becomes obvious when a projects grows big. Besides making things like I describes above possible they are also good to make it easier to test the program since you can then replace the implementation of part of your program (lets say the database access for instace) with a stubbed implementation and by doing that enable you to write automatic tests that verifies other parts of the program (processing the data for instance)
There are no performance reasons to choose interface over direct access to members, rather the opposite since you will call methods that are virtual. This is however a very minor performance penalty in the majority of cases.
Have a look here for more on C++ MI - Why should I avoid multiple inheritance in C++?.
Building up on the "3 Interfaces" section and ybungalobill's answer, consider the typical Observer pattern:
class MyClass : public IScreenListener
{
public:
MyClass()
{
PowerManager::RegisterScreenListener(*this);
}
// Overriding from IScreenListener
void OnScreenOn()
{
// do as you like
}
void OnScreenOff()
{
// do as you like
}
}
Here, the IScreenListener interface provides the two pure virtual methods OnScreenOff and OnScreenOn which are to be implemented in your code. This example is based on Bada's screen listener: it allows you to get notified by such events.
Of course, there are other benefits. Like hiding a code library implementation details from its users, and more.
Interfaces (Pure Abstract classes) provide general functionality. In your example, the class Shape is generic. Which means you cannot have a actual instance (or object) from the class Shape. Where as you can say a Rectangle is a Shape or a Triangle is a Shape. You cannot calculate Area or Perimeter of a Shape unless you know what Shape it is.
Interfaces (Pure Abstract classes) enforce a protocol that a class that is derived from it must implement all of its methods. Otherwise, it also becomes an interface. Interfaces pointers can be sent to functions or other classes and from there you can call the actual derived classes functionality.
For example, if there is a class called Animal from where you derive all animals like dogs, snakes, humans etc, you can send the array of Animal pointers (which are actually instances of it's derived classes) and then call the functionality like Run(), Walk(), Eat() etc. Animal in this case is generic class.
Currently my app uses just Direct3D9 for graphics, however in the future I' m planning to extend this to D3D10 and possibly OpenGL. The question is how can I do this in a tidy way?
At present there are various Render methods in my code
void Render(boost::function<void()> &Call)
{
D3dDevice->BeginScene();
Call();
D3dDevice->EndScene();
D3dDevice->Present(0,0,0,0);
}
The function passed then depends on the exact state, eg MainMenu->Render, Loading->Render, etc. These will then oftern call the methods of other objects.
void RenderGame()
{
for(entity::iterator it = entity::instances.begin();it != entity::instance.end(); ++it)
(*it)->Render();
UI->Render();
}
And a sample class derived from entity::Base
class Sprite: public Base
{
IDirect3DTexture9 *Tex;
Point2 Pos;
Size2 Size;
public:
Sprite(IDirect3DTexture9 *Tex, const Point2 &Pos, const Size2 &Size);
virtual void Render();
};
Each method then takes care of how best to render given the more detailed settings (eg are pixel shaders supported or not).
The problem is I'm really not sure how to extend this to be able to use one of, what may be somewhat different (D3D v OpenGL) render modes...
Define an interface that is sufficient for your application's graphic output demands. Then implement this interface for every renderer you want to support.
class IRenderer {
public:
virtual ~IRenderer() {}
virtual void RenderModel(CModel* model) = 0;
virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) = 0;
// ...etc...
};
class COpenGLRenderer : public IRenderer {
public:
virtual void RenderModel(CModel* model) {
// render model using OpenGL
}
virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) {
// draw screen aligned quad using OpenGL
}
};
class CDirect3DRenderer : public IRenderer {
// similar, but render using Direct3D
};
Properly designing and maintaining these interfaces can be very challenging though.
In case you also operate with render driver dependent objects like textures, you can use a factory pattern to have the separate renderers each create their own implementation of e.g. ITexture using a factory method in IRenderer:
class IRenderer {
//...
virtual ITexture* CreateTexture(const char* filename) = 0;
//...
};
class COpenGLRenderer : public IRenderer {
//...
virtual ITexture* CreateTexture(const char* filename) {
// COpenGLTexture is the OpenGL specific ITexture implementation
return new COpenGLTexture(filename);
}
//...
};
Isn't it an idea to look at existing (3d) engines though? In my experience designing this kind of interfaces really distracts from what you actually want to make :)
I'd say if you want a really complete the answer, go look at the source code for Ogre3D. They have both D3D and OpenGL back ends. Look at : http://www.ogre3d.org
Basically their API kind of forces you into working in a D3D-ish way, creating buffer objects and stuffing them with data, then issuing draw calls on those buffers. That's the way the hardware likes it anyway, so it's not a bad way to go.
And then once you see how they do things, you might as well just just go ahead and use it and save yourself the trouble of having to re-implement all that it already provides. :-)