I'm currently developing an application using SFML. My biggest concern at the moment is making a layer of abstraction over the library, so I can easily change it to something else if needed. What I'm struggling with is designing an abstraction that's intuitive and not leaky.
An example: drawing in SFML is done using drawable objects (implementing sf::Drawable
) and objects capable of rendering them (sf::RenderTarget
).
Say I want to wrap those and create my own IDrawable
:
class IDrawable {
public:
virtual void draw(IRenderTarget& target) const = 0;
};
Even though it looks nice, in order for the concrete classes to achieve their goal, they somehow still need to exchange information specific to SFML, i.e. IRenderTarget
has to declare an abstraction breaking method, such as
virtual sf::RenderTarget& impl() = 0;
The only solution I can think of is creating concrete classes that require all library-specific parts to be passed via constructor, so there's no cross-class communication of library-specific data. This way, IDrawable
would change to:
class IDrawable {
public:
virtual void draw() = 0;
};
Another solution would be abusing the friending mechanism, but I guess that's not great, either.
In other words -- is there an approach for wrapping a 3rd party library, so that the created abstraction is not leaky (doesn't require public accessor methods that break the encapsulation)?