Design Questions about static factory classes

R

Rhino

Something else.

LocalizationFactory lf = new LocalizationFactory();
lf.setLocale(new Locale("FR", "fr"));
X x = lf.getX();
Y y = lf.getY();
Z z = lf.getZ();
That seems pretty much the same as Approach 2 to me, except that the
class is called LocalizationFactory instead of LocalizationUtils. Am I
missing something?

Is it considered a best practice to put Factory in the name of a utility
class that uses static getInstance() methods and private constructors? If
so, I have no problem doing that.
 
R

Rhino

True.

But the problem I describe is not that problem.

I am describing the problem of:
- developers being good at English
- operators being good at English
- for political reasons the GUI's are not in English but the
local language
- something is not working and the developers get some screen
shots and they can only say WTF
I see what you meant now. Yeah, that could be tricky! Then again, if the
GUI is identical except for the labels on the fields or buttons, then all
you really need to do is look at the English version of the GUI and
translate from there. So, if the leftmost menu item on the menu says
"Shizglop", just look at the leftmost menu item on the English version of
the GUI and it should be clear that "Shizglop" means "File".

Foreign language error messages are going to be a lot harder though. It's
not going to be apparent that "Floomba patixet snarblot" means "Please
enter password" ;-) Unless every error message contains a visible message
number like "XYZ123 Floomba patixet snarblot"; then you just look up
XYZ123 (assuming that's a unique message number) and then find that same
message in your English ResourceBundle.

A little tedious for sure but workable in a pinch. Or, you can spend time
and money finding someone who knows English and the local language. Mind
you, I would like to think that at least some of the better educated
people in the local office speak both the local language and English
moderately well, possibly well enough to get the essence of the problem
fairly directly....
 
R

Rhino

Hey, don't look at me. I got the list of locales handed to me from
someone else, and he got it from someone else, and i assume that
someone who knew what they were doing drew it up. Or at least, i hope
so; all i can assume is that someone who had the authority to do it
did it.


And then deploy the JAR and reboot. Not so hot if you're hoping to run
a global ecommerce site.
I didn't realize you needed to reboot to get the new Jar to take effect.
That's lousy. Isn't it possible to simply refresh the new Jar in place
without rebooting? I'm pretty sure Tomcat lets you redeploy a Jar without
stopping Tomcat first but my Tomcat skills are rusty so I may be
wrong....
The system is a web application. We attach a locale to each user
session. We have a component near the top of the servlet container's
request processing chain that looks at the incoming request, and the
existing user object if there is one, and sets the locale accordingly.
When a class needs to know the current locale, it gets hold of the
user object for the current request (via some sort of thread-local
variable or some such) and asks it. So, no class inside the system has
any concept of its own locale - they always use the 'current locale',
where that's something that can be different in different threads that
are running at the same time.
I see. That sounds like a pretty reasonable design for your needs.
 
R

Rhino

There may be few ethnic Germans left in those countries.

But there are a lot of people that wants to do business
with German companies.
Oh! So applications are being deployed in German because the locals will be
communicating with head office in German, not because the locals are German
speakers! I hadn't considered that possibility. It makes sense though; some
of the Slavic countries still educate some of their people in the German
language despite their very bad memories of Hitler and WWII. I took a short
Russian course once and the teacher, a native Russian, had also studied
German quite extensively.

Also, I seem to remember a Pole telling me that Russian, which used to be
mandatory in Polish schools during the Cold War, has now been made optional
and many students are choosing to study German and other languages instead.
I suppose the eastern Europeans will take advantage of those students to
work with your system in German while they await eventual translation to
Hungarian, Polish or whatever....
 
M

Martin Gregorie

Foreign language error messages are going to be a lot harder though.
It's not going to be apparent that "Floomba patixet snarblot" means
"Please enter password" ;-) Unless every error message contains a
visible message number like "XYZ123 Floomba patixet snarblot"; then you
just look up XYZ123 (assuming that's a unique message number) and then
find that same message in your English ResourceBundle.

A little tedious for sure but workable in a pinch. Or, you can spend
time and money finding someone who knows English and the local language.
Mind you, I would like to think that at least some of the better
educated people in the local office speak both the local language and
English moderately well, possibly well enough to get the essence of the
problem fairly directly....
I think you'll find that this is precisely the reason why DEC (while they
existed) and IBM tend to put such ugly prefixes on all their error
messages.

Its also easy to go further: given such tags its easy to support centre
software to take a trace etc. from a site anywhere in the world and and
make it understandable to the support guy no matter what language he
speaks. If you're supporting a multi-language application then IMO such a
translation package should automatically be a part of the project.
 
A

Arne Vajhøj

I see what you meant now. Yeah, that could be tricky! Then again, if the
GUI is identical except for the labels on the fields or buttons, then all
you really need to do is look at the English version of the GUI and
translate from there. So, if the leftmost menu item on the menu says
"Shizglop", just look at the leftmost menu item on the English version of
the GUI and it should be clear that "Shizglop" means "File".

Foreign language error messages are going to be a lot harder though. It's
not going to be apparent that "Floomba patixet snarblot" means "Please
enter password" ;-) Unless every error message contains a visible message
number like "XYZ123 Floomba patixet snarblot"; then you just look up
XYZ123 (assuming that's a unique message number) and then find that same
message in your English ResourceBundle.

Under good circumstances it is not that hard.

But over the phone in the middle of night ...

Arne
 
A

Arne Vajhøj

Oh! So applications are being deployed in German because the locals will be
communicating with head office in German, not because the locals are German
speakers! I hadn't considered that possibility.

It is more like:
- people learn German for commercial reasons
- the software offers a few languages but not the native language
- they pick German because the prefer that over the other alternatives

Very few apps support all European languages. It is rather common to
support English, Spanish, French and German. And let the users pick the
one they understand best.

Arne
 
A

Arne Vajhøj

That seems pretty much the same as Approach 2 to me, except that the
class is called LocalizationFactory instead of LocalizationUtils. Am I
missing something?

Maybe not.

I just wanted to make sure that the Local could be set once (either
constructor or setter) instead of multiple times in the get instance
methods or set methods on the individual objects.
Is it considered a best practice to put Factory in the name of a utility
class that uses static getInstance() methods and private constructors? If
so, I have no problem doing that.

I would tend to put factory in the name of a factory class. It
describes what it does.

Util more indicates a utility method = a method that does
something that the calling code could do in multiple lines,
but has been centralized in a method.

Arne
 
A

Arne Vajhøj

Maybe not.

I just wanted to make sure that the Local could be set once (either
constructor or setter) instead of multiple times in the get instance
methods or set methods on the individual objects.


I would tend to put factory in the name of a factory class. It
describes what it does.

Util more indicates a utility method = a method that does
something that the calling code could do in multiple lines,
but has been centralized in a method.

And X, Y and Z obviously does not have private constructors,
because then LocalizationFactory could not instantiate them.

Arne
 
A

Arne Vajhøj

I didn't realize you needed to reboot to get the new Jar to take effect.
That's lousy. Isn't it possible to simply refresh the new Jar in place
without rebooting? I'm pretty sure Tomcat lets you redeploy a Jar without
stopping Tomcat first but my Tomcat skills are rusty so I may be
wrong....

If you can discard the classloader, then you can do that instead
of restarting the JVM.

But it is still an interruption of production.

In tomcat that is what happens when you restart just the app
and not the entire server.

Arne
 
R

Rhino

If you can discard the classloader, then you can do that instead
of restarting the JVM.

But it is still an interruption of production.

In tomcat that is what happens when you restart just the app
and not the entire server.

Arne

Whatever happened to the time-honoured tradition of maintenance
windows? I don't think I've ever heard of a system that was truly 24 x
7. All of them used to have scheduled downtimes (or at least the
option of having downtimes as needed) for things like taking backups
and so forth. Do real-life Internet online systems _really_ promise 24
x 7? Don't the executives and/or lawyers build in at least some
provisions for downtime into their contracts?

I'm sure that people buying systems push for those downtimes to be as
brief and infrequent as possible but surely their must be _some_
provision for it in web-based systems? Or am I behind the times?
 
R

Rhino

Do you just want to support western languages?

Or do you also want to solve the difficult problems?







Catch the exception but display something else that the exception text.

Exceptions texts are for log files to be handed over to developers.

For user input I don't even think that you should throw an
exception. Maybe just test and tell the user to correct.

Bad user input is not really exceptional enough to justify an
exception.

I'm not disagreeing with you but isn't there some leverage to be
obtained from using the same message to do both: inform the user of a
problem and write it to the log if it is sufficiently severe?

I suppose you would argue that the two cases are mutually exclusive:
any situation serious enough to justify a log message would generate
its message in an entirely different way (from a different place) than
a "user error" message....

So, am I safe in assuming that serious developers are generating "user
messages", like bad input on a form, from ResourceBundles and
"serious" errors for logs and such things from some other source,
perhaps hard-coded within the class itself?
 
R

Rhino

On 22-05-2010 15:05, Rhino wrote:
Catch the exception but display something else that the exception text.
Exceptions texts are for log files to be handed over to developers.
For user input I don't even think that you should throw an exception.
Maybe just test and tell the user to correct.
Bad user input is not really exceptional enough to justify an exception..

I disagree. We've had arguments about the proper use of exceptions on this
newsgroup before, so i recognise that this is a matter where opinions
vary, but exceptions seem like a perfectly acceptable option for dealing
with bad user input to me. They might not be the right solution in every
situation, but they are an option that can be considered.

Of course, i wouldn't show the exception's error message to the user. An
approach i've seen is to do something like:

public class ValidationException extends Exception {
        private final String validationKey;
        private final Object[] parameters;
        public ValidationException(String validationKey, Object.. parameters) {
                super(format(validationKey, Locale.getDefault()));
                this.validationKey = validationKey;
                this.parameters = parameters;
        }
        public String format(Locale locale) {
                return format(validationKey, locale);
        }
        private static String format(String validationKey, Locale locale) {
                ResourceBundle bundle = ResourceBundle.getBundle("ValidationMessages", locale);
                String pattern = bundle.getString(validationKey);
                MessageFormat fmt = new MessageFormat(pattern, locale);
                return fmt.format(parameters);
        }

}

ValidationExceptions have a message in the language of the default locale
(or you could hardcode this to english if you wanted), which can be used
in logging and so on, but can also supply their message in other
languages, as needed.

If you put on a getter for the fields, then code that handles them can
also act on the key and parameters in other ways, as appropriate, if
simply printing the messasge is not adequate. Although in this case, you
should probably be using subclasses rather than switching on the contents
of the key. If you do subclass, you can refine the above approach by
pushing the parameters down into subclasses, accessed via an abstract
getParameters method in the base class. That lets you construct the array
on the fly from meaningful fields:

public class AgeTooYoungException extends ValidationException {
        private final int actualAge;
        private final int requiredAge;
        // constructor
        protected Object[] getParameters() {
                return new Object[] {actualAge, requiredAge};
        }
        // getters

}

Code which catches this and is interested in the ages can then discover
them via proper getter calls, rather than having to scrub about in an
untyped parameter array.

Another refinement is to add a field which somehow indicates which bit of
user input was wrong - a simple string key might be enough. The UI code
can then attach the error message to the right bit of the UI simply by
matching that up.
I'm glad you jumped in on this point, Tom. I thought for a second that
opinions were united on the idea that exceptions had no place in
notifying users about "user errors" (as opposed to "system errrors").
That's a "good news, bad news" scenario as I see it: if everyone
agreed how to do it, it would be up to me to conform with the
concensus and I wouldn't have to think about what should be done very
much. But if there are different schools of thought on the issue, I
could show any reasonable approach in my "code portfolio" and still be
okay, although I might have to be able to defend whatever approach I
used against the other approaches.....
 
A

Arne Vajhøj

Whatever happened to the time-honoured tradition of maintenance
windows? I don't think I've ever heard of a system that was truly 24 x
7. All of them used to have scheduled downtimes (or at least the
option of having downtimes as needed) for things like taking backups
and so forth. Do real-life Internet online systems _really_ promise 24
x 7? Don't the executives and/or lawyers build in at least some
provisions for downtime into their contracts?

I'm sure that people buying systems push for those downtimes to be as
brief and infrequent as possible but surely their must be _some_
provision for it in web-based systems? Or am I behind the times?

It depends on the context.

For many internal systems then nightly downtime is still
acceptable.

But the world has become global. It is always work hours
somewhere on the planet.

Public internet systems like Google and FaceBook does
not close a couple of hours every day.

Huge multinational corporations with offices in almost
all timezones can not shutdown business critical system
a couple of hours every day.

Nightly downtime still exists but it is definitely
out of fashion today.

Many business system still have weekly/monthly
scheduled downtime though.

But Google/FaceBook types does not even have that.

Arne
 
A

Arne Vajhøj

I'm not disagreeing with you but isn't there some leverage to be
obtained from using the same message to do both: inform the user of a
problem and write it to the log if it is sufficiently severe?

I suppose you would argue that the two cases are mutually exclusive:
any situation serious enough to justify a log message would generate
its message in an entirely different way (from a different place) than
a "user error" message....

So, am I safe in assuming that serious developers are generating "user
messages", like bad input on a form, from ResourceBundles and
"serious" errors for logs and such things from some other source,
perhaps hard-coded within the class itself?

In most cases I don't think the exception text would
tell the end user anything.

Let us say that you have developed an accounting program and
the code throws an exception telling that it could not
load the JDBC driver.

No point in telling an accountant that. He don't know what
JDBC is.

You tell the accountant that there were a configuration error
and that he should contact his IT department.

You write in the log file what the problem is and when IT
support look at the log file, then they know what the
problem is.

Of course there are cases where the message text from the
exception can be used in the end user error text. Just don't
display class names, stack traces etc..

Arne
 
A

Arne Vajhøj

....
I'm glad you jumped in on this point, Tom. I thought for a second that
opinions were united on the idea that exceptions had no place in
notifying users about "user errors" (as opposed to "system errrors").
That's a "good news, bad news" scenario as I see it: if everyone
agreed how to do it, it would be up to me to conform with the
concensus and I wouldn't have to think about what should be done very
much. But if there are different schools of thought on the issue, I
could show any reasonable approach in my "code portfolio" and still be
okay, although I might have to be able to defend whatever approach I
used against the other approaches.....

It will not get you thrown out the door. But if the call stack between
throw and catch is less than 2 levels, then I would consider it
bad style. Much better with something that test and return true
or false.

Arne
 
A

Arne Vajhøj

That tends to lead to very artificial handling of the result of the
input processing. To me, it makes a lot of sense to have a conversion
method that normally returns the converted value, and throws an
exception if it cannot do so because of an error in the data it is
converting.

But when it is user input, then it is really not that exceptional
with format errors.

If it was reading a file that was generated by a system, then I
would consider a format error exceptional.

Even for unexceptional stuff an exception can be practical to
roll back the call stack, but if that is not the case either,
then I don't consider exception attractive.

A very good example is that .NET in 1.1->2.0 supplemented
the int.Parse method with a new int.TryParse method - today
the later is used in >90% of all cases.

Arne
 
T

Tom Anderson

Tom said:
I disagree. We've had arguments about the proper use of exceptions on
this newsgroup before, so i [sic] recognise that this is a matter where
opinions vary, but exceptions seem like a perfectly acceptable option
for dealing with bad user input to me. They might not be the right
solution in every situation, but they are an option that can be considered.

And usually rejected.

Read /Effective Java/ (2nd ed.), "Item 57: Use exceptions only for
exceptional conditions", and the rest of section 9.
No.

Part of the problem with exceptions is that they are expensive relative
to conditionals.

True. I wouldn't worry about that in input validation code of this kind
unless i had a profiler screaming at me that it was a problem.

Hmm. Do profilers track the amount of time the JVM spends handling
exceptions?
The other part in this case is that you expect bad inputs - they aren't
exceptional conditions at all.

Your style is your style, tom, and you are absolutely correct to suggest that
one should consider all options. But the design purpose of exceptions is to
deal with out-of-line conditions, and input validation is squarely in line.

I don't agree that bad input is not an exceptional condition; i wonder if
you are confusing 'exceptional' and 'unlikely' or 'unexpected'. I agree
that validating input must be done inline, but not that dealing with
invalid input must be. I'd say exactly the opposite, in fact.

tom
 

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,773
Messages
2,569,594
Members
45,123
Latest member
Layne6498
Top