From: Rhino on 21 May 2010 16:12 In the course of developing test cases for some of my classes, particularly the classes that are static factories, I've developed some confusion about localization. Basically, I'm trying to figure out when I want to have separate constructor and getInstance() methods First, I hope we can all agree that, in an ideal world, every class which can produce text output - even if no text is produced per se, most classed would be capable of producing error messages for Exceptions - should be written so that it can produce that output in the languages of the users of those classes. So, if your utility classes are used in French-speaking countries, text output and/or error messages will be in French and so forth for other languages. Now, I know that many developers will not worry about that - after all, the whole IT field seems to be fairly English-centric - but I aspire to make all of _my_ classes locale- sensitive. Now, with the preamble out of the way, let's get down to brass tacks. Let's say that I want to make a static factory class locale-sensitive but I don't want to force the user to choose an explicit locale every time they try to use the class. That suggests to me that I go one of two ways: 1. Provide two private constructors - one that takes a specified locale and one that uses the default locale - and two corresponding public getInstance() methods, one of which takes a specified locale and one that uses the default locale. Then, if the user is comfortable with the default locale, they use the constructor that doesn't have a locale parameter, otherwise, they use the constructor that has a locale parameter and specify the locale of their choice. 2. Provide a single private constructor that has no locale parameter and a corresponding public getInstance() method. Also provide getLocale() and setLocale() methods so that a user can instantiate with the single getInstance() method and then use setLocale() to alter that locale if it is not to his liking. I thought I'd have a look at the Java API and see what happens there. I got something of a mixed bag. A handful of classes have getInstance() methods that take a Locale parameter, suggesting that they favour Approach 1. A handful of classes have setLocale() methods, suggesting that they favour Approach 2. However, the vast, vast majority of the classes have neither suggesting that they are NOT locale-sensitive and have no capability for changing the Locale at all. So I thought I'd ask the learned people on this group for their thoughts on which approach they'd take when building classes that are meant to be locale-sensitive. I'm sure there are variations on the two approaches I've enumerated so I'm open to "none of the above" answers :-) Personally, I'm leaning towards Approach 2. Approach 1 requires doubling up of constructors and getInstance() methods and makes you reinstantiate the class if you want to change Locales. Approach 2 avoids those extra constructors and getInstance() methods and lets you change Locale by simply doing setLocale(). There may be negative aspects to that which aren't occuring to me though so I hope you will point those out if you see them. -- Rhino
From: Tom Anderson on 21 May 2010 16:28 On Fri, 21 May 2010, Rhino wrote: > First, I hope we can all agree that, in an ideal world, every class > which can produce text output - even if no text is produced per se, most > classed would be capable of producing error messages for Exceptions - > should be written so that it can produce that output in the languages of > the users of those classes. I strongly disagree. Text for the consumption of end-users should be localised; text for the consumption of programmers and sysops should not be. I think the advantages of having a common language for these things outweight the disadvantages of most people not having them in their first language. It's like air traffic control - it's vital for clear communication that i can say "i'm getting the NoMoreJam error", and not draw a complete blank with French acquaintances who've only ever seen NYAPlusDeConfiture and Americans familiar with NoMoreJelly. Having a single language makes googling with error messages and so on a lot more productive, too - and that's a benefit to the speakers of minor languages, who have access to squillions of English search results. Of course, being a native english speaker, i would say that, wouldn't it? > Let's say that I want to make a static factory class locale-sensitive > but I don't want to force the user to choose an explicit locale every > time they try to use the class. That suggests to me that I go one of two > ways: Look up 'resource bundles'. They're the standard way of producing localised messages, and are absolutely what you should use here if you really want to do this. They use the current locale, so they leave the onus of setting that correctly on your developers - but they only need to set it once for the whole VM, and then messages everywhere come out in the right language. And those who see the world my way and don't want localised messages can set it to the canonical standard locale - en_GB. tom -- If goods don't cross borders, troops will. -- Fr
From: Rhino on 21 May 2010 19:16 Tom Anderson <twic(a)urchin.earth.li> wrote in news:alpine.DEB.1.10.1005212118590.16922(a)urchin.earth.li: > On Fri, 21 May 2010, Rhino wrote: > >> First, I hope we can all agree that, in an ideal world, every class >> which can produce text output - even if no text is produced per se, >> most classed would be capable of producing error messages for >> Exceptions - should be written so that it can produce that output in >> the languages of the users of those classes. > > I strongly disagree. Text for the consumption of end-users should be > localised; text for the consumption of programmers and sysops should > not be. I think the advantages of having a common language for these > things outweight the disadvantages of most people not having them in > their first language. It's like air traffic control - it's vital for > clear communication that i can say "i'm getting the NoMoreJam error", > and not draw a complete blank with French acquaintances who've only > ever seen NYAPlusDeConfiture and Americans familiar with NoMoreJelly. > Having a single language makes googling with error messages and so on > a lot more productive, too - and that's a benefit to the speakers of > minor languages, who have access to squillions of English search > results. > You raise VERY good points which I totally failed to consider. That is a great example of how this newsgroup serves as a valuable sanity check on my thinking. I was really thinking primarily of messages that end-users, not system administrators, would see and was trying to accomodate the end-users. I failed to allow for the system administrators. So is there a middle ground that would accomodate both groups? Generating a message in one language for the end-user and a different language for the system administrator, perhaps in the logs? Hmmm, this needs some thought.... > Of course, being a native english speaker, i would say that, wouldn't > it? > Hey, we all have our biases and preferences; nothing wrong with that as long as we are aware of them :-) >> Let's say that I want to make a static factory class locale-sensitive >> but I don't want to force the user to choose an explicit locale every >> time they try to use the class. That suggests to me that I go one of >> two ways: > > Look up 'resource bundles'. They're the standard way of producing > localised messages, and are absolutely what you should use here if you > really want to do this. They use the current locale, so they leave the > onus of setting that correctly on your developers - but they only need > to set it once for the whole VM, and then messages everywhere come out > in the right language. And those who see the world my way and don't > want localised messages can set it to the canonical standard locale - > en_GB. > Sorry, I though it en_US was the canonical standard ;-) I say that as a Canadian, just to show that I'm not trying to push my own variant of English :-) I'm very familiar with resource bundles at a detail; I use them quite frequently. I'm not quite clear on the "big picture" though. I lack any significant real-world experience with how "multilingual" systems are written with Java. For instance, if I were a developer whose native language was French would I typically install a French-language JVM, read the Java API in French, and write my system so that it never chose or changed Locales? Would my classes simply make use of the Resource Bundles I had written in French and would I leave it up to foreign purchasers of my system to simply translate the ResourceBundles for their own languages? Also, is there much need for systems in which the user can switch languages on the fly? In other words, let's say I'm working in a system that uses French language ResourceBundles but am finding that the French is not to my liking - maybe it's Quebecois instead of Parisian - and I realize that I will understand better in my second language, English, which I learned by watching MTV. Would a system typically have the capability of letting the user invoke a switch to another language via setLocale()? Or would I install an English-language JVM and run my system on that? Hold on, that doesn't quite make sense. I don't recall any language selection option any time I've installed Java. The language of the JVM comes from a system property which I can presumably change. Hmm, I wonder if I should take a minute and switch my language to see what kind of output I get from core Java classes. Will the message that comes with my Exception be in the newly-chosen language?.... I should answer this question for myself with a bit of experimentation.... Thanks for helping me get back on the right track! -- Rhino
From: Lew on 21 May 2010 19:49 Rhino wrote: > Let's say that I want to make a static factory class locale-sensitive but > I don't want to force the user to choose an explicit locale every time > they try to use the class. That suggests to me that I go one of two ways: > > 1. Provide two private constructors - one that takes a specified locale > and one that uses the default locale - and two corresponding public > getInstance() methods, one of which takes a specified locale and one that > uses the default locale. Then, if the user is comfortable with the > default locale, they use the constructor that doesn't have a locale > parameter, otherwise, they use the constructor that has a locale > parameter and specify the locale of their choice. Why do you want to provide factory classes at all? > 2. Provide a single private constructor that has no locale parameter and > a corresponding public getInstance() method. Also provide getLocale() and > setLocale() methods so that a user can instantiate with the single > getInstance() method and then use setLocale() to alter that locale if it > is not to his liking. This can be a good solution but can exacerbate concurrency issues. Generally, not always but generally one should prefer class instances to be immutable - everything is fixed in the constructor and assigned to final member variables, and guarded against changes in the internal state of referenced objects. Such objects are inherently thread safe. Even in a single-threaded context, the object that takes a read-only Locale at construction never risks being used with a different Locale than expected. Once you make the Locale (or any other attribute) mutable, you have to add complexity to guarantee that the attribute has a suitable value at any given time, lest it change between accesses. For example, collections class instances with an active iterator will throw a 'ConcurrentModificationException' if the collection state changes during the iteration. This can happen in single-threaded or multi-threaded contexts. In addition to the complexity in the collection class of checking for and throwing the exception, there is complexity in the client code of preventing and/or checking for the exception. Or failing to do so and having a sudden program crash. You have to weigh the advantages of having an object whose Locale (or any other attribute) is fixed at construction for the lifetime of the object, versus the advantages of permitting an object to alter its state, and perhaps to live longer. There are also disadvantages to both approaches. (For example, long-lived objects can put more strain on the garbage-collection mechanism.) As for letting "a user ... alter that locale", it's not the user who alters the locale, it's the code in response to a user action. You could just as easily instantiate a new object with a different locale in response to a user action as mutate an existing object. In your particular case, I'd lay dollars to doughnuts that an immutable Locale attribute is the better solution. -- Lew
From: Lew on 21 May 2010 19:50
Lew wrote: > Why do you want to provide factory classes at all? Oops. I mean "factory methods". -- Lew |