(note: I used Java to make it easer to explain my question, but the actual language is irrelevant for this dilemma)
TL; DR: I have a wrapper around some underlying class. At which point should I instantiate the underlying class (in the constructor, in a separate method, on first use) and why?
Lets say, for example, that I want to create a simple class to read from a file (it can actually be anything where the main functionality of a class depends on one or more underlying classes, but file reading seemed simplest to explain). This class will wrap around/simplify another class called File. In the past, I'd implement my file reader class this way:
class MyFileReader { private File file; public MyFileReader(String filename) { this.file = new File(filename); } public String read() { this.file.read(...); } } Thus, the creation of my object immediately opens the file (if there's a possibility that the file doesn't exist, I'd throw an exception in the constructor).
Nowadays, I'd usually implement that class like this:
class MyFileReader { private File file; private boolean isOpen = false; public void open(String filename) { if (this.isOpen) close(); this.file = new File(filename); this.isOpen = true; } public void close() { if (this.isOpen) { this.file.close(); this.isOpen = false; } } public String read() { if (this.isOpen) { this.file.read(...); } } } In other words, object creation is separate from actually opening the file (if there's a possibility that the file doesn't exist, I'd make the open method return a boolean indicating whether the class managed to open the file successfully) and it's possible for the object to exist without any file currently open.
Finally, another approach which I rarely used is to open the file "lazily", when it's first needed, like this:
class MyFileReader { private File file; private String filename; private boolean isOpen = false; public MyFileReader(String filename) { this.filename = filename; } public String read() { if (!this.isOpen) { this.file = new File(filename); this.isOpen = true; } this.file.read(...); } } Now the question is - which one of these approaches is the best? And, since the answer is probably "it depends", what does it depend on and in which scenario(s) is each of these methods best applied?
close()method even when you open it in the constructor.close()method in the first example (one with the constructor) allow the possibility of the object existing in an invalid state (as explained by @busy_wait in his answer)?