Bad coding habits I usually find that causes a lot of troubles during development

1. Define 1 interface for only 1 class

It’s a good practice to program to interface instead of implementation. However, the interface should be created to implement to many classes. Defining an interface before class implementation causes you waste your time to modify both 2 during development, especially when you refactor the code. I believe that finally the interface you create first time will be completely different one at the end. Besides, many times the interface you create first time cannot use with the second subclass.

The solution is easy, implement a class directly first. Whenever there are 2 classes that require same interface, you can move the implementation to the subclass, change the class to interface, then implement it to the other sub-classes.

2. Create 2 POJOs and Mapper to keep data of complex class twice rather than create an Adapter

Imagine that you are developing the web services, there are many layers including the facade layer, service layer, data layer. When user sends the request, the facade will be the first layer that receive it. Then, it passes to the service layer. Finally, the service layer sends it to the data layer to save into database. On the other way round, clients request data. You will pass the data from data layer to facade layer. There is a practice I usually see during passing data to another layers, it’s a mapper.

Can you see something in the code? The duplicate code in the ProductDTO and Product. You can see there are 2 places to keep name and price. Why don’t we use Adapter?

Then, use the serialize framework to serialize to the particular format. For example, the expire date could be format as a string in JSON response.

Tip: It’s a good idea to trim the string input in the setter before set its value.

3. The setter never validate input, while the getter returns null reference

This is the basic programming that many programmers ignore. Why do we allow the invalid data be set into our object? Why do we allow null to be set to the mandatory field? Is it better to assert the input before set the value?

On the other hand, the getter returns null reference. What would happen if you return null reference. Every place that call this getter must check the null before do any expression in order to prevent NullPointerException. What would happen if you have 50 places call this getter? Finally, you will have lots of the null checking. This will increase a lot of complexity in the system because you need to check the null reference and other logic condition together like

On the other hand, if you make sure that every method will never return null reference, you code will be like

4. Do not clone object, but send or return the reference

This is many developers think that it’s not a big deal, but it causes a lot of bugs because they allows other classes change the object state especially if you need to save that data into database or send it to other services.

From the code above, the value of A will be changed. Finally, you send and/or save the wrong data. The easy solution is to return a new object or clone the object.

5. Use too many if/else to check the type rather than using Map

Have you ever check the type of data before execute the particular statement?

Why do we still have this kind of nasty code like this? Is it better to use Map?

From now, it doesn’t matter how many types you have. Besides, you can add a new type without any effect to any other code as well. However, you need to create an interface State and many small classes for each type. So, make sure that each condition does the same way.

6. Use libraries for the business logic

Each business has some different logic from others. Even 2 companies that run the same business still have some different logic. If you need to develop any part relate to the business logic, better develop it yourselves. Using open source libraries or from another has limitation. The library might not be flexible enough to fit to all requirements.

7. Do not separate between programming logic and business logic

Separate between ‘what the system can do’ and ‘what the business wants the system does’ are one of the good practice. The business should be able to configure in order to select the execution logic that the system allows to do. It means the system allows to do A, B, C, D. Then the business choose to execute one of them in a particular situation. For example, the system allows to discount the price for X percent if the conditions matches. Then, the business should be allowed to configure the conditions and how many percent (X).

8. Use the value of other system rather than create a mapper

System integration with other systems of other parties are quite challenging. One of the mistakes that many developers do is they usually keep the 3rd parties data in the system rather than define the mapper between other system and our system. For example, if you want to shipping the parcel from seller to buyer, you need to send the shipping information to the courier companies which have a lot of parties. Each courier has their own system with the different status. One of them might define 999 as the success code, while another might define SUCCESS. The most important thing is you ought to define a success status of your system, then use a mapper to map between 999 and SUCCESS into your format.

9. Learn a lot of new things but never learn from the mistakes

If you have developed the system for awhile, you might notice that every system has so many the same problems. Unfortunately, many times causes from developers’, but many developers never learn and repeat it again and again. That’s why we are still not productive. Many times we have to find a workaround solution to solve the problem that should not be a problem. After that workaround, we need to find the second workaround solution because we didn’t solve the root cause. This situation happens again and again. Finally, project delays, so many bugs, and cause other problems.

There are so many example of good and bad practices, so read it, practice it and don’t repeat the history.

Software Engineer and Architect