views:

113

answers:

2

I have several classes with raw data, for example:

public interface Transaction {
   public double getAmount();
   public Date getDate();
}

I need to output formatted versions of this data in several places. For example, I might display the amount as $1,000 on a web page, or 1000.00 on an Excel download. I also want to be able to reuse the same formatting code in different places. Some of it will be simple (like displaying a date in a certain format), but some will be more complex (like displaying different values for one field depending on the value of another field).

My question is: where should I put the formatting code? I can think of a few places:

  • Add methods to the data object like getAmountHTML() or getAmountExcel(). Convenient, but does it make the model and view too closely related?

  • Do the formatting in the template, when displaying the data. Flexible, but since it isn't in a method, I can't easily reuse the same formatting in different places.

  • Create a formatting class for each data class, and give it a reference to the original data object.

I'm going to have a lot of data objects to format, so I'd like to come up with a good approach. Is there anyone with some relevant experience to share?

+2  A: 

IMO, formatting the data is a view concern. If you are using JSTL, you can use <fmt:formatNumber>.

I don't like option 1 because that means you're putting view-concerns into your domain object. There is a potential for method-explosion there (what if you get 5 new formats - are you going to create a method for each one?).

I don't like option 3 either because it seems you're creating a formatting class for each format - this can lead to class explosion for the reasons identified in option 1.

I like option 2. You can combine some aspects of option 3 into option 2. You could have a FormattingService that takes the data and a format and returns formatted data. You could expose the formatting method via a tag that you can use in your view.

Vivin Paliath
+4  A: 

I agree with Vivin that you should not add various methods to your data object to handle every conceivable format. Having the View difine the display string is appropriate.

Another option that you have, which still allows for the view to define the formatter, is to use a sort of Visitor pattern. Here, your Transaction object receives a formatter as a param to a new method:

public String getFormattedString(Formatter f);

The output obviously being a formatted string. This would let you have a single number formatter for each view which could be passed to each different data object for formatting.

akf
+1 I like this - didn't know about the Visitor pattern!
Vivin Paliath
Are you thinking that the data objects would just delegate the formatting to Formatter -- or would they have some of their own formatting code? And wouldn't you need one of these methods for each field you want to format? Just wanted to understand what you had in mind.
JW