0

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 ImageResource hold 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 ImageResource is 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 release methods 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?

4

The problem I see with your approach, that you want to get the internal implementation image out of the ImageResource object. You are basically not assigning enough responsibilities to the ImageResource to be able to do its job, that is why you need to dig into it and do its job yourself.

So the problem is not how to access that image, but your design that needs to access it in the first place.

Ok, so how would you avoid that? Usually every single Component in a UI framework should know how to display itself. AWT has paint(), Wicket has render(), and so on. So your ImageResource should know how to display itself to a screen. This way you don't have to know what's in it.

1

You can create your API as a façade of another UI framework. Simply make sure that you are wrapping object to hide its implementation. If you want to support some part of this framework as an input, create a method that is taking it as a parameter but return wrapped object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.