A primitive is not enough


note: I know String is not a primitive. At least not technically - but the concept equally applies.

String is a nice class. When I was learning to program in C, I was quite annoyed by the fact that standard C didn't have a String type, but you had to use char* instead. Then I discovered C++ and Java, and I was happy with my String. I could do lots of things with a String. I could search for a character in them, replace it, and passing it around happily. I could have objects with lots of Strings to store information. For example, an User could have a password stored as a String. After all, a password is a String, isn't it?

Well, not quite!

In every classic Object Oriented Programming book/article, an object will be defined more or less as an entity that has got data fields and methods that can be called from the outside (i.e. other objects). A primitive, instead, holds a value but doesn't have any methods.

Every respectable password should at least have some very basic security enforced (no less than 6 characters, for example). A password may be valid (for example "notsosecret") or invalid ("dog") following that criteria. A password has a value ("notsosecret", "dog", "password") and a way of checking whether it's invalid (less than 6 characters). Doesn't it seem like the definition of an object? It is indeed!

By having a Password object, you will be allowed to write a validate() method on that object - the method will do all the checks needed with the added value that the validation logic will stay inside the Password object, not polluting other parts of the code (why another class should know about how to validate a password, clearly violating the SRP?), but it will make adding more checks easier (we know exactly what to modify and where).

Another example that comes to my mind is when a method accepts a parameter like int intervalInSeconds. Even if you're lucky and nobody changes that argument name (and you know sooner or later will happen), what if you decide to convert all intervals to milliseconds? Wouldn't it be better to pass a Interval refreshInterval and then use all the utility methods to operate with interval that a class such as Interval provides?

Primitive Obsession (the obsession of using primitives for much more information than needed, losing the possibility to give more information to values) is a code smell that's present in a huge number of projects. By refactoring out and wrapping primitives in first class objects, you both make your code more readable and extensible.