ColorManager

We jumped into the pool filled with collection classes from the implementation of the ColorManager class. Let's refresh the part of the class that is interesting for us now—the constructor:

final protected int nrColors; 
final protected Map<Color, Color> successor = new HashMap<>();
final private Color first;

public ColorManager(int nrColors) {
this.nrColors = nrColors;
first = new Color();
Color previousColor = first;

for (int i = 1; i < nrColors; i++) {
final Color thisColor = new Color();
successor.put(previousColor, thisColor);
previousColor = thisColor;
}
successor.put(previousColor, Color.none);
}

We will use HashMap to keep the colors in an ordered list. At first, the choice of HashMap seems to be strange. Very true, that during the coding of ColorManager, I also considered a List, which seemed to be a more obvious choice. When we have a List<Color> colors variable, then the nextColor method is something like this:

public Color nextColor(Color color) { 
if (color == Color.none)
return null;
else
return colors.get(colors.indexOf(color) + 1);
}

The constructor will be much simpler, as shown in the following piece of code:

final List<Color> colors = new ArrayList<>(); 

public ColorManager(int nrColors) {
this.nrColors = nrColors;
for (int i = 0; i < nrColors; i++) {
colors.add(new Color());
}
colors.add(Color.none);
}

public Color firstColor() {
return colors.get(0);
}

Why did I choose the more complex solution and the unobvious data structure? The thing is performance. When the nextColor method is invoked, the list implementation first finds the element checking all the elements in the list and then fetches the next element. The time is proportional to the number of colors. When our number of colors increases, the time will also increase to just get the next color having one.

At the same time, if we focus on not the data structure that comes from the verbal expression of the task we want to solve (get the colors in a sorted order) but rather focus on the actual method that we want to implement, nextColor(Color), then we will easily come to the conclusion that a Map is more reasonable. What we need is exactly a Map : having one element we want another related to the one we have. The key and the value is also Color. Getting the next element is constant time using HashMap. This implementation is probably faster than the one based on ArrayList.

The problem is that it is only probably faster. When you consider refactoring a code to have better performance, your decision should always be based on measurements. If you implement a code that you only think is faster, practice shows, you will fail. In best case, you will optimize a code to be blazing fast and runs during the application server setup. At the same time, optimized code is usually less readable. Something for something.
Optimization should never be done prematurely. Code for readability first. Then, assess the performance, and in case there is problem with the performance, then profile the execution and optimize the code where it hurts the most of the overall performance. Micro-optimizations will not help.
Did I do premature optimization selecting the HashMap implementation instead of List? If I actually implemented the code using List and then refactored, then yes. If I was thinking about the List solution and then it came to me that  Map solution is better without prior coding, then I did not. By years, such considerations will come easier, as you will also experience.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.81.43