I am currenctly trying to create an API for a UI framework, for a new application. This UI framework is internally implemented using an existing framework, let us say JavaFX. I want to hide the implementation details from the user (the developer using the API), so for instance, when the user addresses an image, I want him/her to use my interface for it, let us call it
ImageResource. In that way the specifics of JavaFX are not exposed to the user, and I am left with the freedom to change UI framework in my implementation at a later point in time, or simply create a new implementation of the API where a different framework is used.
The user would load an image resource through a resource loader, which is part of the API. The loaded resource could then be passed to different functions or containers, that would then work on the image, either displaying it or processing it.
// Load a resource using a resource id, which would probably be a file name or url. ImageResource resource = resourceLoader.loadImage("some/image/id"); // Add the image to some container, which would then have the image displayed. The container // is also of an API interface type. someContainer.addImageResource(resource);
The problem is that the user handles the
ImageResource instances and passes them to other API functions which should then display the image, or in any other way work with the image. So internally the framework should take an instance of an
ImageResource and do something meaningful with the image. Since I do not want to expose the
javafx.scene.image.Image through the interface and I do not want to do an:
instanceof check. I find the
instanceof check ugly, and really destructive towards the whole thought of splitting up the API into smaller interfaces.
But how do I extract the inner image from the interface, so far I have considered:
- Adding a method to the interface returning an instance of a
javafx.scene.image.Image, which would give me all I needed, but at the cost of locking the API to the JavaFX specifics, which I really hoped to avoid.
- Letting the
ImageResourcehold a key, for instance a string identifier to an image, and then in some cenral internal model class, have a map that translated the string id to an image. This could potentially be used to add some, possibility of freeing memory from seldomly used images. At the same time though, it would make it complicated to keep the map clean. When an
ImageResourceis collected by the garbage collector, it would lose a reference to the JavaFX image if it held it internally, but how would I know when to release if from the map, if the image was located centrally? Using manual
releasemethods would just be a source of leaks.
I am not sure if there even exist a good solution to this, right now I am considering simply going with the first approach, and expose the JavaFX classes from the interfaces, but I would very much like to keep these implementation specifics out of the API. Is there any general pattern or thought that could be of value in solving this?