Java Forum / First Aid / April 2004
Code in the Constructor
Shane Mingins - 07 Apr 2004 05:52 GMT Hi
Quick question ..... what is the danger of having processing code in the constructor of a Class ... I ahve inherited an application that was written procedurally using the constructor to process.
Do I have a serious issue?
Thanks Shane
An example ---
public class FtpPutFile { public FtpPutFile(String ftpHost, String ftpUser, String ftpPassword, String ftpRemoteDir, String outfilePath, String outfileName, boolean renameOnCompletion, BufferedWriter logBuffer, FTPTransferType transferType) {
try { PrintWriter pw = new PrintWriter(logBuffer); System.out.println("FTP: Connecting to: " + ftpHost);
FTPClient ftp = new FTPClient(ftpHost, 21, pw, 5000); System.out.println("FTP: Connected");
ftp.debugResponses(true); ftp.login(ftpUser, ftpPassword); System.out.println("FTP: Logged in");
ftp.chdir(ftpRemoteDir); System.out.println("FTP: Directory changed");
System.out.println("Send via FTP: " + outfilePath + outfileName); ftp.setType(transferType); ftp.put(outfilePath + outfileName, outfileName); System.out.println("FTP: File sent");
if (renameOnCompletion) ftp.rename(outfileName.trim(), outfileName.trim() + ".dne");
ftp.quit();
} catch (Exception e) { System.err.println("Exception :" + e.getMessage()); System.exit(1); } } }
Roedy Green - 07 Apr 2004 07:18 GMT >Quick question ..... what is the danger of having processing code in the >constructor of a Class ... I ahve inherited an application that was written >procedurally using the constructor to process. Often you need several aux constructors. You want to avoid duplicating code. As soon as you see yourself doing that, move that code to its own method, or have each constructor call another.
-- Canadian Mind Products, Roedy Green. Coaching, problem solving, economical contract programming. See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
Chris Smith - 07 Apr 2004 13:56 GMT > Quick question ..... what is the danger of having processing code in the > constructor of a Class ... I ahve inherited an application that was written > procedurally using the constructor to process. > > Do I have a serious issue? There isn't really any "danger" here at all. There's just the possibility of a poor abstraction.
If it makes sense to look at the processing as part of the idea of "creating" something, then a constructor (or method called from the constructor) may be a perfectly logical place for it. In your example, though, the client isn't logically creating an FtpPutFile object when they do that stuff, so I'd refactor to move that code to a method with a descriptive name. In general, as a matter of fact, use of a verb or verb phrase as a class name typically indicates that exactly this design error exists.
You can rest assured, though, that this code won't cause any really serious definite problems because of its being in a constructor. It's just messier to work with as a result of poor abstraction.
 Signature www.designacourse.com The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Shane Mingins - 07 Apr 2004 22:32 GMT > You can rest assured, though, that this code won't cause any really > serious definite problems because of its being in a constructor. It's > just messier to work with as a result of poor abstraction. Thanks. A while ago there was a discussion on comp.object that was talking about code in constructors in a general sense and someone commented that in some languages you can get "unusual" code behavior (and Java was mentioned) .... so just wanted to check if it was sertain (or not) that I had an immediate issue or not.
I realise that from a design perspective this is ugly but as there are no existing unit tests and classes are coupled-for-africa changes will take time and effort .... something I will have to deal with at a later stage.
Thanks Shane
 Signature "The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair." -- Douglas Adams
Chris Smith - 07 Apr 2004 23:09 GMT > Thanks. A while ago there was a discussion on comp.object that was talking > about code in constructors in a general sense and someone commented that in > some languages you can get "unusual" code behavior (and Java was mentioned) > .... so just wanted to check if it was sertain (or not) that I had an > immediate issue or not. The only "unusual" behavior associated with constructor code in Java is when it runs. That's often a bit surprising to some people, particularly when there is inheritance involved, and can result in use of values that haven't been initialized yet. If you never call a non- final and non-private method of 'this' from a constructor, you'll be safe. The code in the constructor itself is fine.
Some people also go around with the impression that exceptions in constructors cause big problems. While that's true of C++, it's not true of Java (but handling exceptions can be clumsy sometimes, again with inheritance involved).
 Signature www.designacourse.com The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 08 Apr 2004 03:06 GMT >in a general sense and someone commented that in >some languages you can get "unusual" code behavior (and Java was mentioned) >.... so just wanted to check if it was sertain (or not) that I had an >immediate issue or not. See http://mindprod.com/jgloss/constructor.html and follow the initialisation link.
There are a number of freaky things that happen in constructors when you use virtual methods.
-- Canadian Mind Products, Roedy Green. Coaching, problem solving, economical contract programming. See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
Shane Mingins - 08 Apr 2004 04:18 GMT "Roedy Green" <look-at-the-website@mindprod.com> wrote in message
> There are a number of freaky things that happen in constructors when > you use virtual methods. This seems interesting http://mindprod.com/jgloss/gotchas.html#CONSTRUCTORINIT
"The problem is that instance initialisers / variable initialisation in the derived class is performed after the constructor of the base class"
"If you call methods in your constructor polymorphically, the compiler will not stop or warn you of the initialisation pitfalls awaiting."
I could not think of a legitimate "real" example of this ... but wrote the some code that seems to show the problem. The constructor in the base case calls setName in the derived *before* the variable 'other' is set to the argument passed to the constructor of the dervied class.
Is this the sort of thing you are referring to?
Thanks Shane
 Signature The most intelligent Java IDE around -- http://www.intellij.com/idea/
public class TestConstructorProblem extends TestCase { public void testNotUsingDerivedClassMethods() { Base b = new Derived("Shane", "Nicola"); assertEquals("Nicola", b.getName()); } }
abstract public class Base { protected String name; protected String other;
public Base(String name) { setName(); }
abstract protected void setName();
public String getName() { return this.name; } }
public class Derived extends Base {
public Derived(String name, String other) { super(name); this.other = other; }
protected void setName() { this.name = other; } }
Alex Hunsley - 08 Apr 2004 12:05 GMT > "Roedy Green" <look-at-the-website@mindprod.com> wrote in message > [quoted text clipped - 19 lines] > Thanks > Shane Yup, this is what we're talking about... your original code is alright though, as it doesn't call any other methods, or access non-private class state. (i.e. doesn't access a member variable!)
To echo what other people have said though: a well named and abstracted object will not have a verb in the name, but it may have a *verbal noun*, e.g. 'Helper' or 'Manager' etc. A verbal noun is useful because it gives you some idea of what services a class might offer - it suggests a verb, even if it's a vague one, like 'manager' suggests 'manage'. It all makes sense really, as an object is a thing, i.e. a noun, not a verb. (And you could think of instances as proper nouns, as in "*the* apple" vs. "apple".)
(Verbal noun definition btw: http://www.bartleby.com/61/1/V0060100.html - maybe what I'm thinking of isn't quite a verbal noun, but it seems to fit quite well!)
Also, a constructor should do things that are required to set up the object for use, and not much more. In your example, your constructor is doing too much - it's actually doing the ftp put - but this in part stems from your choice of class name. If instead you chose a class name like "FtpHelper", then it would be more natural to just construct an FtpHelper object, and then call a method like ftpPut() on it.
Another commonly seen but not great idea is to do any sort of GUI realisation activity in the constructor (by which I mean showing a window and similar things). Also I prefer not to even do population of GUI items in a constructor - I prefer to make it explicit by having a populate() method. IMO showing/hiding of a GUI item should always be done explicitly, with a call to show() or similar.
Anyway, I am digressing like a diggity thing, so I'll stop.
alex
Daniel Sjöblom - 07 Apr 2004 18:27 GMT > Hi > [quoted text clipped - 3 lines] > > Do I have a serious issue? The code is some of the ugliest I've seen in a while, but no, it doesn't do any direct harm.
But consider that the constructor actually creates an object. What is the point of creating an object that doesn't hold any data and doesn't have any methods? Also, constructors can't return anything, so they aren't really functions.
When converting purely procedural code to OO, you'll either want to convert the functions to static methods, with the class only acting as a namespace, or if you have functions that do something different to one data structure (say, like string.h in C), that data structure should be made a class, and the functions using the struct should be made member functions (methods.) That's something to start off with anyway.
<OT> If you want to use java as a purely procedural language, classes should only hold static methods and public fields. Oh, and mark every class final. Not recommended. </OT>
 Signature Daniel Sjöblom Remove _NOSPAM to reply by mail
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|