I'm currently developing an application using [SFML][1]. 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][2]. 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)? [1]: https://www.sfml-dev.org/ [2]: https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/