Java Deep

Pure Java, what else

Monthly Archives: August 2015

Optional in collections

Sometime it is argued that the type Optional is worth being used in collections. It allegedly solves the problem of e.g.: HashMap that returns null in case there is no mapping for a key as well as when the value null is mapped to the key. If you use a Map<Optional<Something>> then you can clearly separate a missing mapping and an absent value. And that way you are one level deeper in the rabbit hole.

First of all

you can

tell if a key is mapped to null or not mapped without using Optional. There is the method containsKey(). This is one more method call to separate the non-mapped key from a mapped null value. However calling the methods of Optional is also. So what is the point? On the other hand

you do not need

to tell if the key is mapped to null or the mapping is missing. If there is a difference in your program code between the two cases then you created the code for the business login in a wrong way. This is certainly code smell. Think of null as “nothing”, and instead of thinking “null is assigned to the key ‘aaaaaarrghhh'” say out loud: Nothing is assigned to the key ‘aaaaaarrghhh’. You see? There is no difference except that all look at you now in the office.

And using optional as a value in a Map

you will

end up one level deeper in the rabbit hole after a while. Code lives independent life. It is not only you, who develop it. In large organizations there are developers who are certainly drunk when code. (This is the only reasonable explanation for some code.) They will soon populate your Map<Optional<Something>> with

  • null values,
  • absent Optional values
  • and even with Optional object that wrap something else but not your “Something“.

From time to time, if you are lucky you may even find some non null, non absent Optional<Something> values.

Some thoughts about yagni

Yagni means “You Aren’t Gonna Need It”. This is a phrase used many times to refuse the development of some features that may be needed later but not now. Yagni means that you should develop a feature in your code, which is needed and when it is needed and not sooner.

Why do we have this term at all? Do developers tend to develop features that are not needed? It should be like that otherwise there would not be any expression for the phenomena. It may seem crazy for someone not knowing how a programmer thinks and works.However the fact is that programmers do like to develop features that were not requested.

Why do programmers tend to develop features that are not needed?

Reasons and Problems of Yagni

Coding a feature, which is similar to one I have just developed is easier than something totally unrelated. Developing similar features one after the other is simpler than developing one, then doing something totally different and developing the second one weeks later. The developer is “on the track”. She knows how to develop the feature having just developed a similar one.

The problem is that many times the feature will not be needed (1). Even if it is going to be needed there is high probability that it will be needed a bit (or a lot) different from what has been developed (2). The code developed but not in use by business has costs attached to it (3), but no business benefit.

If (1) the feature is not needed in the future the investment devoted to the development of the feature is wasted. It does not matter who is financing it. It may be financed by the business but many times I see that it is financed by (usually junior) developers creating the feature after work hours. They argue that it was a good way of learning, practicing. However I strongly believe it is not a good way of learning. It is a way someone lies to him/herself. The cognitive patterns in the brain prevent to admit: “I was wrong and wasted my time.” One can do more valuable things during that time and doing free work is not professional. There are better ways for learning or practicing something. Be professional!

If the feature is needed but in a different format (2) you have to modify it. It is not likely that the cost of the development at the first place and the modification is cheaper than developing the feature the correct way upfront.

Even if it is needed and exactly the way it was developed the costs (3) associated with the prematurely developed features include maintenance, increased complexity debugging, maintaining and costs related to the delayed delivery of the features that were needed in early stage. It is likely that you do not deliver feature “ONE” faster if developed it together with feature “TWO”.

When Yagni is Good

The only situation when Yagni seems to be valuable is when developing a feature A alone needs extra coding that gets useless and erased when the latter feature is developed. For example you need feature A and to have it without the other feature B you need some extra classes that you will just throw away when you finished the development of B.

The reasoning is good as formal logic. Only the basic assumption that such situation exists may not be true. The need for some extra code for A but useless when B is developed is a code smell. In that case you have to think about how to develop those extra classes so that they can be usable also by the feature B later on.

But wait a minute! Isn’t that yagni by itself? Developing some classes differently just because some later features will need it differently? No, it is not. To get that correct we have to distinguish between

Feature Yagni and Structure Yagni

So far I was speaking about feature yagni. Structure yagni is different and is not really a yagni. Well, most of the cases.

Wording is important! I do not advocate writing the classes for A in a way so that they can be used by B but nothing else. What I recommend is that you check your style and coding to find the reason why the extra classes would be thrown away. If you can write it different way so that they can be used when B is implemented then they are reusable (by definition). In that case your code is generally good (or at least better) style.

That way implementing good style code, creating clean code, good data and class structures is not yagni. The implementation of a feature not needed yet: that is yagni.

Refactoring is not Yagni

Even if creating clean code needs more work than the Q+D solution this extra coding, including some extra classes is not yagni. We do develop code that is not strictly needed by any business function. That way when there is some not soo good code and we refactor it is also not yagni.  This is not l’art pour l’art. It is needed by business and sometimes, if the seniors and BA do their jobs right business people even know it.

Practice avoid yagni

Writing code that does not develop extra features and is not especially prepared to be ready for extra features not needed yet (yagni), but are open for extension is hard. It is a kind of art and needs a lot of practice. Actually this is what we do when we strictly follow TDD. We develop a test first and it fails. Then we deevelop the code that is minimally needed to fulfill the test. Then we create the next test and so on. When doing TDD you never create a new test while there is a test failing and you never develop any (non test) code unless there is a test failing and you develop the code to pass the test, but nothing else.

This is exactly the practice to develop without yagni. It works on the small scale. When you start you hate it first. It seems to be slow and cumbersome like dacing hogtied. But after a while it becomes a habit, your code style improves and without realizing your way of thinking changes and you get the yagni free design on higher levels.