0

I want to make GUI applications such that the non-GUI code is independent from the GUI one (let's say I'll use Java 8 and Swing for example). The goal is that I could hypothetically change the GUI API/library, or the kind of UI, for example shifting from a GUI to a console output, without modifying the non-GUI code (also in observance of the Open/Closed principle).

In particular, my question is about how to handle exception messages so that they can be output to any UI: let's say that I have try/catch blocks in my non-GUI code, like this (in the example I'm using Java but the language is irrelevant):


try {
    do something;
} catch (AnException e) {
    System.err.println("Exception message");
}

Obviously the println wouldn't be executed in the GUI, so the user would be unaware of the message. My goal is to show the exception message through the GUI. A simple way would be to swap the println for a GUI print method, but doing this my code wouldn't be independent from the GUI. How to solve this problem? Which is the standard approach (if there's such a thing) to deal with this problem?

The question can be generalized to any kind of output message in non-interface-related code.

  • 1
    Define an interface that declares a Print method. In your application, provide an implementation that has the behavior you want. In your exceptions, use the Print method provided by the interface. – Robert Harvey Jun 18 at 16:10
  • Thank you sir. Is this the default way of handling this kind of problem? – Fabio Nardelli Jun 18 at 18:30
  • It is a way that fulfills the conditions you described in your question. – Robert Harvey Jun 18 at 22:13
  • If I use an interface, I have to instantiate an object of a class implementing it. Which is the best way to make the choice of this class as much as possible independent? I was thinking of using a Factory Method design pattern, using a class provided with a create method which takes some parameters and establishes the class to instantiate. A trivial implementation would use a simple string as argument, for example "Swing" to indicate the use of a Swing-related concrete class. But this way the caller would still be forced to know about Swing. Could you please suggest me a better way? – Fabio Nardelli Jun 19 at 14:53
  • What do you mean by "better?" The way you propose sounds reasonable. – Robert Harvey Jun 19 at 15:27
0

There are different ways of dealing with the described situation. And before you start a "best practice"-debate - none of them is "better" than the others in general, you need to evaluate which one fits best to your case.

A simple solution for the case of an "exception" is by simply not catching the exception in some non-GUI code and let it bubble up to the GUI layer, which then catches and displays it. That is what exceptions are primarily made for - they can be thrown at place where the code cannot handle or output them, and catched upstream at a place where this is possible.

If this is not sufficient because you want the non-GUI code to generate the exception message, catch the original exception and rethrow one with a better text:

try {
    do something;
} catch (AnException e) {
    throw new AnotherException("My specific exception message");
}

A more general solution was scetched by Robert Harvey in the comments: the idea of using "callbacks". The calling "GUI" provides a functional callback for a certain output function (in form of an interface implementation, or by using the functional programming concepts from Java 8). The callback is passed to the non-GUI code which then calls it whenever it wants to output some text.

There is well-known an architectural pattern which utilizes these techniques to make a full separation between a GUI-framework dependendent layer and a framework-independent layer, it is called Model-View-Presenter. The (GUI-framework dependent) View implements a full interface for all basic UI functionality, but does not provide any UI logic. The UI logic is located in the Presenter class instead, which requires an instance of this interface and makes use of it to control the UI. That way, the Presenter is not bound to a specific UI framework. Maybe that is what you are looking for.

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.