Design Questions about static factory classes

R

Rhino

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.
 
T

Tom Anderson

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
 
R

Rhino

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 :)
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!
 
A

Arne Vajhøj

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.

I think you are too ambitious.

Not everything need to be internationalized.

Some forms of output are not even possible to internationalize
(especially languages outside of the western countries can
be difficult).

You should focus on the output that is rich (looks good, has
advanced capabilities).

GUI's (both fat client and web) plus print intended for
advanced printers (not line printers).

Drop it for console IO, log files, print for line printers etc..
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.

I prefer #2 with the note that you set Locale on the factory
not on the objects created by the factory.

Arne
 
L

Lew

Rhino said:
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.
 
A

Arne Vajhøj

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.

I would expect developers, testers and operators to understand
English too, but unfortunately it is not uncommon for customers
to require internationalization for operations. In Europe
both Germany and France often require that. Scandinavia
not so often.
Of course, being a native english speaker, i would say that, wouldn't it?

The argument for a common language is still valid, but you may have
a problem if the language chosen was french.
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.

For the text then resource bundles should be the solution, but there
are a lot more to internationalization than just text.

Arne
 
A

Arne Vajhøj

Tom Anderson<[email protected]> wrote in
And those who see the world my way and don't
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 :)

Give the state of US and UK software industry then I think we can say
it is.

And my guess is that Tom meant US 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?

I think it depends a lot of the context you develop software in.

Global or local development?

global => do development in English
local => pick English or local language as you prefer

Are you developing single-customer project-style software or
multi-customer product-style software?

product => internationalize, have English and then add to
supported languages as customers require them (note that
customers can want 3 things A) English version, B) local
version C) Choice of English for local for end users

project => whatever the customer wants

And then we have not even talked about interesting countries
like Belgium and Switzerland with multiple official languages
(Canada is easier because one of the languages is English).

That is not a clear answer, but it is a complex question!
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()?

See above.

Customer is king.
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....

That problem is not so important. You would not want to display
Java exception text to end-users anyway.

Arne
 
T

Tom Anderson

And those who see the world my way and don't

Give the state of US and UK software industry then I think we can say it
is.

And my guess is that Tom meant US English.

Certainly not! en_GB is the canonical form, and en_US is merely a popular
but subordinate deviation.

tom
 
T

Tom Anderson

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?

If you were French, you might.

But in general, i don't think there's any correlation between the
languages of the system and of its developers. A French developer might
well have his machine's locale set to fr_FR, and he might well read
documentation in french (if there is such a thing - i've seen some Sun
documentation translated into japanese, but rarely into European languages
other than english), but he ought to have his JVM set to run in one of the
languages the system is being built for, and he ought to routinely test it
in other such languages.

For instance, i'm currently on a project which will roll out to 23
countries in the first wave. They're all European and North Amererican,
and in a slightly weird twist, to begin with we're only supporting
english, french, and german as languages. So, if you're a native of the
UK, the US, Canada, France, Switzerland, Luxembourg or a few other places,
you have your own language, but if you live in Hungary or the Netherlands,
you'll have to be able to read english, or in some cases in eastern
Europe, german. In the second wave, Korea will be added, and for that,
there will be korean. I assume that in later waves, there will be proper
localisation into national languages, but i haven't heard about that. By
that point, such localisation would not require programmer input (or at
least only a tiny bit) - the client's content management team will be able
to add new locales and their corresponding translations to the system
themselves. We're keeping translations in a database rather than resource
bundle files, so they can do this to a running system without having to
modify the codebase.

Anyway, we're British, the client's programmers are American (well,
they're in America, and are either American or Indian), the contractors we
had involved a while ago were Indian (a mix of hindi, telugu and malayalam
speakers), and the client's HQ, including their infrastructure guys and
the virtual machines where we all work, is in Denmark. We all work in
english. I think the JVM default locale is en_US throughout.

So, a daily feature of our project is an Indian programmer in an office in
the US using a machine in Denmark to look at content in german which will
be shown to customers in the Czech Republic.

I have no idea if any of this answers your question.
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?

I wouldn't expect to have to install a second JVM. I also wouldn't expect
to be able to change locale on the fly - i might try it, but i wouldn't be
surprised if it didn't work. I would expect that i'd be able to get what i
wanted by killing the system and restarting with the following parameters
added to the java command line (assuming a Sun java):

-Duser.language=en -Duser.country=GB
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....

Experimentation is often a very good thing to do.

tom
 
A

Arne Vajhøj

I would expect developers, testers and operators to understand
English too, but unfortunately it is not uncommon for customers
to require internationalization for operations. In Europe
both Germany and France often require that.

Which can be a bit problematic when having a global team
that needs to fix bugs related to a GUI in German or
French.

Arne
 
T

Tom Anderson

Lew said:
Arne said:
And my guess is that Tom [sic] meant US English.

Tom said:
Certainly not! en_GB is the canonical form, and en_US is merely a
popular but subordinate deviation.

It has ever amazed me how well the Brits speak English. Awesome!

Some of them even write it well, though rarely as well as the Irish.

And of course, it's the Scandinavians who are the real masters of it.

tom
 
M

Mike Schilling

Tom said:
Lew said:
Arne Vajh?j wrote:
And my guess is that Tom [sic] meant US English.

Tom Anderson wrote:
Certainly not! en_GB is the canonical form, and en_US is merely a
popular but subordinate deviation.

It has ever amazed me how well the Brits speak English. Awesome!

Some of them even write it well, though rarely as well as the Irish.

And of course, it's the Scandinavians who are the real masters of it.


I was thinking of Shaw, Wilde, Joyce, Synge, and Yeats.
 
R

Rhino

And those who see the world my way and don't

Give the state of US and UK software industry then I think we can say
it is.

And my guess is that Tom meant US English.


I think it depends a lot of the context you develop software in.

Global or local development?

global => do development in English
local => pick English or local language as you prefer

Are you developing single-customer project-style software or
multi-customer product-style software?

product => internationalize, have English and then add to
supported languages as customers require them (note that
customers can want 3 things A) English version, B) local
version C) Choice of English for local for end users

project => whatever the customer wants

And then we have not even talked about interesting countries
like Belgium and Switzerland with multiple official languages
(Canada is easier because one of the languages is English).

That is not a clear answer, but it is a complex question!
It certainly is. I'm trying to write code that will be easily usable by
non-English speakers. But my code isn't actually being written for a
specific customer at this time, other than me. At the moment, I'm trying
to put together a sort of code portfolio. I'm hoping it will show
prospective employers or clients that I am culturally sensitive enough to
write code that will work in multiple languages and knowledgeable on how
to do it. In other words, I don't just want to claim that I am culturally
sensitive but then have no code to back that up. When they challenge me
to prove that I can write code that works for customers in various
locales, I want to be able to point them to some decent examples where I
have done that. I'm just trying to figure out the best way to do that
right now.....

My "code portfolio" is basically a set of classes that generates my
resume in various formats and makes use of various utility classes to do
some of the grunt work. It makes sense to me to internationalize/localize
at least the utility classes to prove that I can do it.
See above.

Customer is king.

Agreed! And if I was writing my code for an actual paying customer, I
would certainly let him/her decide how much i18n they want.
That problem is not so important. You would not want to display
Java exception text to end-users anyway.
Really? I find that a surprising thing to say. Maybe we're not talking
about the same thing.

I'm thinking of a situation like completing a form in a GUI. The customer
has to enter his date of birth. Let's say that I can't use a JSpinner for
some reason; it can't do everything I need it to do. The customer is
given a simple JTextField for entering a date. Clearly, the customer
would have many opportunities to enter bad data. He could type in 1985-
15-31 when he meant to type 1985-05-01; the first value is obviously a
bad date since there are only 12 months in the year, not 15. My practice
is to write edits that check for that kind of mistake and generate an
exception, typically IllegalArgumentException, with a clear error message
that reminds the user that there is no such month as '15'. Naturally, the
customer might not be an English speaker so I put all such messages in
ResourceBundles so that other bundles can easily be added for any
languages that I support.

How would you handle such a situation?
 
R

Rhino

If you were French, you might.

But in general, i don't think there's any correlation between the
languages of the system and of its developers. A French developer
might well have his machine's locale set to fr_FR, and he might well
read documentation in french (if there is such a thing - i've seen
some Sun documentation translated into japanese, but rarely into
European languages other than english), but he ought to have his JVM
set to run in one of the languages the system is being built for, and
he ought to routinely test it in other such languages.

For instance, i'm currently on a project which will roll out to 23
countries in the first wave. They're all European and North
Amererican, and in a slightly weird twist, to begin with we're only
supporting english, french, and german as languages. So, if you're a
native of the UK, the US, Canada, France, Switzerland, Luxembourg or a
few other places, you have your own language, but if you live in
Hungary or the Netherlands, you'll have to be able to read english, or
in some cases in eastern Europe, german.

Sorry for the off-topic digression but I just can't help but admit to
some surprise that some eastern Europeans still know German. Stalin and
his eastern European brothers were pretty ruthless about exiling or
killing their German residents in the immediate aftermath of WW II. I had
thought the German language was pretty much non-existent in the former
Warsaw Pact area by this point.... Based on what you're saying, it
appears that I was premature in assuming an absence of German in those
countries.
In the second wave, Korea
will be added, and for that, there will be korean. I assume that in
later waves, there will be proper localisation into national
languages, but i haven't heard about that. By that point, such
localisation would not require programmer input (or at least only a
tiny bit) - the client's content management team will be able to add
new locales and their corresponding translations to the system
themselves. We're keeping translations in a database rather than
resource bundle files, so they can do this to a running system without
having to modify the codebase.
What codebase changes concern you? If you do ResourceBundles correctly,
there really aren't any code changes. You simply throw ResourceBundles
for the appropriate languages into the jar and you should be good to go,
right?
Anyway, we're British, the client's programmers are American (well,
they're in America, and are either American or Indian), the
contractors we had involved a while ago were Indian (a mix of hindi,
telugu and malayalam speakers), and the client's HQ, including their
infrastructure guys and the virtual machines where we all work, is in
Denmark. We all work in english. I think the JVM default locale is
en_US throughout.

So, a daily feature of our project is an Indian programmer in an
office in the US using a machine in Denmark to look at content in
german which will be shown to customers in the Czech Republic.

I have no idea if any of this answers your question.
I'm not sure either ;-) But it is interesting!

Do your classes have constructors (or getInstance() methods that
establish a Locale? Do you have setLocale() methods in your classes? If
you don't use either approach, how do you set the Locale and how do you
change it if it needs to be changed?
I wouldn't expect to have to install a second JVM. I also wouldn't
expect to be able to change locale on the fly - i might try it, but i
wouldn't be surprised if it didn't work. I would expect that i'd be
able to get what i wanted by killing the system and restarting with
the following parameters added to the java command line (assuming a
Sun java):

-Duser.language=en -Duser.country=GB
Yeah, that's a more convenient approach. I'd forgotten about setting the
locale from the command line.
Experimentation is often a very good thing to do.
Now if only I had time to do everything I'd like to do .... ;-)
 
L

Lew

Really? I find that a surprising thing to say.

Exceptions are not for users, they're for code.
Maybe we're not talking about the same thing.

You are.
I'm thinking of a situation like completing a form in a GUI. The customer
has to enter his date of birth. Let's say that I can't use a JSpinner for
some reason; it can't do everything I need it to do. The customer is
given a simple JTextField for entering a date. Clearly, the customer
would have many opportunities to enter bad data. He could type in 1985-
15-31 when he meant to type 1985-05-01; the first value is obviously a
bad date since there are only 12 months in the year, not 15. My practice
is to write edits that check for that kind of mistake and generate an
exception, typically IllegalArgumentException, with a clear error message
that reminds the user that there is no such month as '15'. Naturally, the
customer might not be an English speaker so I put all such messages in
ResourceBundles so that other bundles can easily be added for any
languages that I support.

You generate an error message for the customer, but it's not in the exception,
it's in what *handles* the exception.

In fact, with input validation, you wouldn't want to create, much less throw
an exception at all. Bad data is not part of the exceptional flow, it's part
of the normal flow and should be handled with conditionals.

Furthermore, runtime exceptions like IllegalArgumentException are for
programmer errors, not situational problems like failure to locate a file
(FileNotFoundException) or socket woes (SocketException), which are covered by
checked exceptions. You certainly don't want to talk to the user about
programmer errors.
How would you handle such a situation?

Not use exceptions at all.
 
R

Rhino

Lew said:
Why do you want to provide factory classes at all?
(I saw your amendment saying you meant factory METHODS in that sentence.)

Actually, you and/or Eric (and maybe some others) persuaded me to use
factories for my utility methods several weeks back when I was asking
about the best way to set up my StringUtils class. You're not changing
your mind and advising me against that now are you?
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.

Agreed. That's exactly what I meant; I just phrased it crudely in an
attempt to be brief. Clearly, the user is going to choose a different
language/locale from a GUI or something like that and is certainly not
going to type "new Locale("XX", "yy")" somewhere.
You
could just as easily instantiate a new object with a different locale
in response to a user action as mutate an existing object.
which is why I'm struggling with this. When there are several ways to do
something, I'm not always clear on how to choose between them....
In your particular case, I'd lay dollars to doughnuts that an
immutable Locale attribute is the better solution.
Would it be helpful here to post one of my utility classes? One of them,
LocalizationUtils, is very short. Right now, it has two private
constructors, one that takes a Locale and one that doesn't, two
corresponding getInstance() methods, a getLocale() and a setLocale(),
plus three other short methods. I'm sure some of that is redundant; I'm
just trying to figure out which constructors and methods to eliminate to
make the final version of the class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top