martes, 1 de marzo de 2011

Using messages with parameters in Java

Messages are one of the most important parts of a software. They enable the application to inform the user about errors, warnings or other important information. That's why we should give them special consideration.


Users: Sometimes developers find it difficult to write a simple and clear message. We are used to writing sentences in a cryptic computer language, so it's natural for us to also write cryptic messages (that are almost impossible for an average user to understand).

Developers: We must appreciate that a user expects messages in his natural language, not in machine language... Yes, I know it sounds strange and difficult but we need to make an effort... It is also important to consider translators; the simpler and clearer the message, the more likely it is to be correctly translated.

Dilbert.com


Example:
there is a process which executes some kind of business logic. Imagine the process fails in the middle of the execution with the following error:
RUNTIME EXCEPTION
...and now try to imagine the average-user's face!
Yeah, I know all the developers are saying: "no problem, we can dive into the application logs, we can debug the code, etc."; but the user isn't able to do that. This message is a "show stopper" for them... and we don't want this situation to happen.

As I said before, a message must be written in a "natural" language and must try to be as helpful as possible, specially when dealing with errors. In the previous example, a good message could be:
The invoice IV-1000004 has not been posted yet. Remember that invoices must be posted before running this process


For developing that we could think about creating two different messages, one for "The ", and the other one for " has not been posted yet. Remember that invoices must be posted before running this process". After that, in the Java code, we could easily concatenate the invoice number between these two messages... Wrong!!
Again, the developer must consider the localizer who is faced with translating two meaningless strings of text.

Translating is a very difficult (and time consuming) task. A localizer must be provided with meaningful phrases (where the context is clear) for translating, otherwise the translation will almost certainly be inaccurate.


So, the best way to keep both our users and localizers happy would be to create the message with the invoice number as a parameter.

In Java we have all the flexibility to implement our own parametrized messages framework. In my developments I use the String.format(java.lang.String, java.lang.Object...) method, which is very similar to the C's printf().
Let's see how it works:

* The error message included into the Application Dictionary is: "The invoice %s has not been posted yet. Remember that invoices must be posted before running this process". Observe the %s, that represents our parameter.

* The Java code for passing the invoice document number to the message is as easy as:
String message = String.format(Utility.messageBD(new DalConnectionProvider(),
"BLOG_INVOICE_NOTPOSTED", getLang()), invoiceDocNo);

As usual, we recover the "BLOG_INVOICE_NOTPOSTED" message from the Application Dictionary using the Utility.messageBD() method.
Then, the recovered message is used as the first parameter of the String.format() static method. The second parameter is the invoiceDocNo string (IV-1000004 in the example), that will replace the %s of our message.


With this very basic considerations, users and localizers will be very happy and the product will be even better.

No hay comentarios:

Publicar un comentario