I'm currently developing an application using SFMLSFML. 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 leakyleaky.
An example: drawing in SFML is done using drawable objects (implementing sf::Drawablesf::Drawable
) and objects capable of rendering them (sf::RenderTargetsf::RenderTarget
).
Say I want to wrap those and create my own IDrawableIDrawable
:
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. IRenderTargetIRenderTarget
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, IDrawableIDrawable
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 -- areis there any general guidelinesan 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)?