OK to do UI in constructor?

S

Steve Brecher

In a calculation application I want to create a new class that interacts
with the user to get a problem specification. Currently the application UI
is via the console, so problem specification is a series of prompts and
responses. This series would occur only once per instance. Is there a
reason not to do this UI within the class's constructor rather than as a
separate method? E.g. (from the class's creator's point of view)
ProblemSpec spec = new ProblemSpec();
result = calculation.result(spec);
rather than
ProblemSpec spec = new ProblemSpec();
spec.GetSpecFromUser();
result = calculation.result(spec);
 
W

Wesley Hall

Steve said:
In a calculation application I want to create a new class that interacts
with the user to get a problem specification. Currently the application UI
is via the console, so problem specification is a series of prompts and
responses. This series would occur only once per instance. Is there a
reason not to do this UI within the class's constructor rather than as a
separate method? E.g. (from the class's creator's point of view)
ProblemSpec spec = new ProblemSpec();
result = calculation.result(spec);
rather than
ProblemSpec spec = new ProblemSpec();
spec.GetSpecFromUser();
result = calculation.result(spec);

I would tend to avoid doing lots of blocking IO inside constructors.

You may want to consider writing a helper class that will allow you to
interact with your users. A class with static helper methods will do
this quite nicely so you have something like...

int value = Console.getIntInput("Please enter your age:");

The getIntInput method would print the argument to the screen, and
handle input data (including the parseInt call and validation). Then
your code would look more like this...

int int1 = getIntInput("Please provide a number:");
int int2 = getIntInput("Please provide another number:");
String string1 = getStringInput("What is your name:");
double double1 = getDoubleInput("What is your bank balance:");

ProblemSpec spec = new ProblemSpec(int1, int2, string1, double1);
long result = spec.calculateResult();

Something like this would be cleaner in my opinion.
 
S

Steve Brecher

Wesley Hall said:
I would tend to avoid doing lots of blocking IO inside constructors.

If it's OK to do any, shouldn't it be OK to do lots? More generally, what
is the reason not to do blocking I/O in constructors?
You may want to consider writing a helper class that will allow you to
interact with your users. A class with static helper methods will do
this quite nicely so you have something like...

int value = Console.getIntInput("Please enter your age:");

The getIntInput method would print the argument to the screen, and
handle input data (including the parseInt call and validation). Then
your code would look more like this...

int int1 = getIntInput("Please provide a number:");
int int2 = getIntInput("Please provide another number:");
String string1 = getStringInput("What is your name:");
double double1 = getDoubleInput("What is your bank balance:");

ProblemSpec spec = new ProblemSpec(int1, int2, string1, double1);
long result = spec.calculateResult();

Something like this would be cleaner in my opinion.

That's pretty much what I've already got, but the parsing and validation
code is substantial enough that I want to move it out of my main class (the
one containing: public static void main(...)) into its own class. E.g.,
strings that are input each have to be validated as to content, numbers as
to range, etc.; and some of the validation is contextual, depending on
previous responses.
 
G

Graham

Constructors are just used to ensure that objects are placed into a
valid state when first instantiated. They are not designed to do "real"
work (which is why they don't have a return value and they are not
inherited).

Use constructors to initialise the object, and then call methods to
perform operations.

Graham
http://www.modernsecuritysolutions.com
 
R

rxreyn3

Constructors should only contain code that is safe. If you have
something that can throw an exception, put tn in a method so you can
properly handle the error, or have the calling object handle any
exceptions that are thrown. Client code shouldn't have to worry about
an exception being thrown when it creates a "NEW" instance of an
object. i.e. bad:

try{
Object a = new Object()
}catch(Exception e)
{
....
}

Obviously this could be avoided by catching all throwables in the
constructor, but it is not a good programming paradigm to have business
logic contained in a constructor.

Ryan
 
A

Alex Hunsley

Steve said:
In a calculation application I want to create a new class that interacts
with the user to get a problem specification. Currently the application UI
is via the console, so problem specification is a series of prompts and
responses. This series would occur only once per instance. Is there a
reason not to do this UI within the class's constructor rather than as a
separate method? E.g. (from the class's creator's point of view)
ProblemSpec spec = new ProblemSpec();
result = calculation.result(spec);
rather than
ProblemSpec spec = new ProblemSpec();
spec.GetSpecFromUser();
result = calculation.result(spec);

As another reply said: avoid doing any 'real' work in the constructor.
Two good reasons for doing this:

1) The order of superclass setup (e.g. static versus none static member
var instantiation) can lead to confusion and head banging. Keep as
little in the constructor as possible.

2) Objects are nouns (things), not verbs (actions)! Therefore it can be
surpising when constructor do too much. 'new' should mean just that -
make a new somehting - but not actually do anything yet.

lex
 

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

No members online now.

Forum statistics

Threads
474,270
Messages
2,571,102
Members
48,773
Latest member
Kaybee

Latest Threads

Top