MagMax Blog

Aviso: En este blog puede encontrar código!

Constructors as Simple as You Can

| Comments

This week I realized about the difference between an ugly constructor and a pretty one. It is curious how easy doing it well is and how cheap it is, so I am going to share my point with you, waiting your comments.

Since I began to work, I have done lots of ugly things, so do not face me up if you find something mine done in a different way :D The real goal is to improve yourself day after day!

Throwing exceptions

A constructor that throws exceptions is something really ugly. A constructor should prepare the object to be used, not to do its thing. And if it do not do any real job, it should not throw any exception.

When I say that it do not launch exceptions it does not mean to capture them: I’m saying that it do not raise them because it do not need them. Every activity done by the constructor must be so simple that it cannot fail: initializations and nothing more. No operations. Complex things must be placed on methods.

There is nothing uglier than a constructor that throws exceptions. It is the last thing you hope and it is the last thing you want other people to find.

When the constructor has exceptions, this must be the least code to instantiate it:

public class Example {
public Example() throws exception {
}

}
// […]

try {
Example example = new Example();
} catch (Exception e) {
}

Null pointer exception

If a constructor do no operation, it cannot access any invalid pointer. Constructors should only do assignments, and nothing more.

Constructors with parameters

From time to time, an object requires a parameter to work. In these cases, it is right to require it in the constructor.

When the number of parameters is too high (that is, TWO), then we should look another way to do it. If the constructor is requiring so many parameters, it is possible that it be rapping the Single Responsability Principle.

Another of my old habits that I saw a lot is to have a constructor with N parameters, allowing to initializate each of its private attributes. Experience showed me that it is a very bad habit… almost in all cases.

Using Java, it is a bad habit from every point of view. Which one is the parameter order? If I have 3 parameters… Have I to try the three unique parameter combinations, at least two with two arguments and anotherone with the three ones? And what if I need the fourth private attribute? How many combinations should I do?

Using other languages, like Python, when arguments can be named, our code is not affected by previous assertion. Despite of that, we will have another problem: what if I do not need one of the arguments or if I need to change its name?

For example… With the next piece of code:

public class Example {
private int value1;
private int value2;
private String juntaLaTrocola;
private String gamusino;
public Example() {}
public Example(int value1){}
public Example(int a, int b) {}
public Example(String juntaLaTrocola) {}
public Example(String gamusino, String juntaLaTrocola() {}

}

I have lots of questions

  • The third constructor, shoud I use first the value1 or value2?
  • Why is not possible to build an object only with “gamusino”?
  • Why cannot combine numbers and strings? Is it because the developer was tired (just like in this case)? Is it because I must not? Is it because they were added later?

In addition, if you inherit that class, you have to overwrite all of these methods!!!

Examples? JDialog has 16 different constructors.

Tired constructors

Some time ago I implemented a constructor that was parsing a whole XML file. It looked horrible, but I couldn’t find another way of doing it better. Anybody see any logic in this matter? Now I do not.

When we have a constructor doing so many work, how can we improve our code? We cannot use the pattern a method a class, because we will have a class with a constructor that will do, again, all the work. And if it does not, why have we two classes? We could use the second one instead the first class.

It is not so difficult to find: Java API has methods that launches exceptions or make lots of work (NOTE: searching some examples, I found no one launching esceptions, but I know I saw them; did I find them in third party code?):

RMIConnectorServer(JMXServiceURL url, Map<String,?> environment, RMIServerImpl rmiServerImpl, MBeanServer mbeanServer);

JDialog(Window owner, String title, Dialog.ModalityType modalityType, GraphicsConfiguration gc);

The solution: Factories

Some times I need two constructors because there are severan ways to use the object. For example: I have a class that is connected to a database and can be used in two different ways: with a real database or a memory one.

Here I have a problem. One of the constructors will need an argument and the other one, none. It is not logical to use another system to build the object… Maybe.

After doing in this way again and again, I found a better way to do it: By using a method that makes the object. So, I can differ between one build steps and the others. That is: I will have the method createInMemory and createInfFile. Optionally I will be able to transform the constructor as private to avoid is incorrect use (but I do not like too much this approach).

With so easy transformation, I get constructor that is not raising any exception and, in addition, I have a beautiful way to build the object with some instructions, being more verbose when I have to modify it.

Another advantage: If I need to add more “constructors”, like a remote database, it will be enough to add more factories: createRemote.

An example:

public class DataAccess {
public DataAccess() {}
public static DataAccess createInMemory() throws SQLException{
DataAccess result = new DataAccess();
result.setConnectionString("in memory");
result.buildDatabase();
return result;
}
public static DataAccess createMySql() throws SQLException{
DataAccess result = new DataAccess();
result.setConnectionString("mysql");
if (!result.hasDatabase())
result.buildDatabase();
return result;
}

}

Abstract factories

I think it is very important to write code that can grow, without any limit when it is born. Using factories you can easily evolve it into an Abstract Factory, giving it more functionality with baby changes.

Tests

When a complex constructor is being used, you have lots of drawbacks to test it. But when the constructor is simple and the complexity is inside the operations, it is easier to test it, because you can build the object inside the setUp method being sure that it is not going to fail. But when you use complex constructors, there are no way to test it.

If any operation (method) raises an exception, the operation is telling you something. If it is the constructor the one that throws it, you cannot be sure about the operation that was been performed in that moment. This is what makes tests difficult and makes very hard to mock the object.

Conclusion

As our classes have to be complex, do not get the code dirty since the very begining and let’s try with simple constructos. When the constructor is the one who makes the job, which ones are the methods responsabilities? Let’s delegate that job.

Comments