Be careful with primitives!

flajos's picture

Several times a development team has relatively short time to implement certain functionality. In these cases, the major goal is to implement the desired functionality before the strict deadline, and because of that, the source code is not or poorly documented. Furthermore, developers are apt to code the required functionality as fast as possible, which causes decreased understandability of the code. In this post, I’ll show simple and easily applicable tips to make the code more understandable by introducing classes.

Fowler published a book about refactoring techniques, and also in this book he gave a collection of bad smells. Bad smells refer to that something in the code that “stinks”, it is not a real problem, but it can be. For example, if a method has too many parameters, it may cause a problem, which is called as Long Parameter List by Fowler. A related problem to LPL, if we use heavily primitive data types instead of defining our own types; it was named as Primitive Obsession by Fowler. There is one more related smell to the previous two, which was named as Data Clumps. It happens, when we use the same data bundle several times.

In this post, I’ll show an example for the Long Parameter List bad smell. Furthermore, it can be also considered as an example for Primitive Obsession. If we suppose that the same data bundles appear in other locations of the code, then it can be an example for Data Clumps as well. So, let's see the example (implemented in Java):

  public void buyProduct(String customer, String company, String address, String addressC, 
                                            boolean grantee, int age, String phone, String phoneC, String product){
        ...
  }

Method buyProduct is responsible for storing a purchase of a customer in an e-commerce application. This method has eight parameters, some of them have almost the same name, these are the address and the addressC, the phone and the phoneC. The maintainer of this code can suspect, based on the order of the parameters, that parameter address represents the address of the customer, while parameter addressC represents the address of the company (he can suspect the same in case of parameters phone and phoneC). On the other side, it can happen, that the original author did not deal with the order of the parameters, just listed them randomly. Yes, it can happen, just observe that the words customer and company starts with the same letter, therefore there is a real chance that parameter address is the address of the company not the customer. It may cause that the product delivered to the company and not to the customer!

And the problem derives from only four parameters of the example method (customer, company, address and addressC). What could happen if a method has more than 10 or 20 parameters? It could be a potential problem!

So, what can be the solution for these cases? Most of the times, a simple solution is to group the related parameters into classes (Preserve whole object and introduce parameter object refactoring techniques published by Fowler). In the case of this example it means to introduce Customer and Company classes:

  public void buyProduct(Customer customer, Company company, String product){
        ...
  }

Afterwards, in the method body of buyProduct the developer can access the same data through the customer and company objects. By this modification of the code, the maintainer can understand it more easily than previously. Furthermore, she can understand it more precisely, which really matters. So, you may think we are ready: the buyProduct method has only three parameters, which is absolutely not a long parameter list. Ok, it is true, but we can make it better. Let's see that its third parameter, product, is a simple String. Therefore it can be considered as a primitive obsession bad smell, if we set aside from the fact that Java defines String as a class. Furthermore, there is a high chance that the buyProduct method will need further data about the product, e.g. the price, the production date and so on. Following this thought, the method could be changed in the future, creating a long parameter list again. Why couldn’t we precede this problem by introducing a Product class? In this way we got a method, where all of the parameters are user defined classes:

  public void buyProduct(Customer customer, Company company, Product product){
        ...
  }

To sum up, by introducing Customer, Company and Product classes the buyProduct method became more easily understandable, and by this way more easily maintainable. Furthermore, it has been done with only a little effort! So, my final suggestion is, be careful with primitives!