How much should be done in the constructor

This is a matter of theory, I assume that I am using this standard procedure for this.

If I have a Constructor method that performs many tuning operations that collect data, etc., should I store the "all things" construct in the constructor or try to call other methods from within the constructor (to view the code basically), or should I just initialize everything that I have and leave other things to be considered later if they are really necessary?

Here is an example.

I am creating an object that is basically a collection manager. It needs to read data from a file, and it stores it inside an array.

I use a constructor to create an object with basic properties and read data later, or I have to read all the information and set up an array inside the constructor, which saves time later, but takes extra time here, or I need to do something in the lines

public myConstructor(String filename) { data = readDataIn(filename); } 

This is not actual code, just an example of outsourcing for different methods for "pretty code", and not a super-long constructor method. I can tell 5-6 short and good methods that only the constructor can access.

+4
source share
3 answers

The designer must do enough work to get the instance in a state that satisfies his contract. Each method should do enough work to fulfill the contract by the method and leave the instance in a state that satisfies its contract.

It is very rarely necessary for a constructor call to cause side effects or change its inputs. This is not often required to satisfy a contract. For example, the connection class should not touch the network during construction. Since it must be closed, a closed state must be part of its contract, so the standard of "fairly large work" indicates that the designer puts it in a ready, but not yet open state.

Your specific example connects your class to the file system. You will probably get a more verifiable, more general class, using Guava Files to do the reading and taking the line with the contents. You can get the convenience of a file system constructor by writing the convenient static MyClass fromFile(String path) function static MyClass fromFile(String path) factory, which makes new MyClass . This moves the part of your code that is associated with the file system outside the part that interacts with instance variables, reducing the number of possible interactions for testing. As others have noted, dependency injection is another good way to get around.

+8
source

Really depends on your API style. Note that you can have multiple constructors, for example:

 public MyThing(String filename) { } public MyThing(FileInputStream filestream) {} public MyThing(File file) { } public MyThing(byte[] rawdata) { } 

in which it is wise to combine the file upload operation into a method or two (opening the file and analyzing the file)

+2
source

In this case, I will use dependency injection, so your constructor will need data that has already been calculated, and sends the calculation back to what the constructor calls. I could provide an additional static factory function that does all this complicated setup so that it is convenient to build this object (for example, in tests), but at least it would be possible for a user of this class to come up with a smarter one (maybe parallel or lazily-initialized) way to create this class.

0
source

All Articles