Code Smells : Bloaters (Primitive Obsession, Long Parameter List, Data Clumps)

Primitive Obsession

If there is a code smell I often misses, then it has to be Primitive Obsession. Quite honestly, I have been guilty of falling for Primitive Obsession more than once. This particular type of Code Smell refers to the tendency of Developers to use primitive types instead of small objects for stimulating certain fields.  For example, one of the most common form of primitive obsession is usage of strings to represent Phone Numbers or Zip Codes.

 

Clearly, Phone Numbers and Zip Codes have their own formats and having primitive string to represent it would mean, you need to do additional checks (mostly repeated preconditions) in every method which utilizes it to ensure they hold the integrity needed by the stimulated object.  Instead, the Users could Replace Data Value With Object along with the associated behavior ( and validation checks).

 

Another possible technique associate itself when primitive fields are used in Method parameters. There might be cases when same group of parameters are used by more than one methods. Let’s consider the following code for example.
public IList GetBirthdays(DateTime startDate, DateTime endDate);
public IList GetAnniversaries(DateTime startDate, DateTime endDate);
public IList GetOtherLandmarks(DateTime startDate, DateTime endDate);
As seen in the above code,  two date time parameters, namely StartDate and EndDate are repeatedly used by 3 different methods. You could introduce a object here replacing the repeated parameters. The above code could be rewritten as following

 

public IList GetBirthdays(DateRange Dates);
public IList GetAnniversaries(DateRange Dates );
public IList GetOtherLandmarks(DateRange Dates );

 

This technique of Refactoring is known as Introduce Parameter Object as observed by Martin Fowler. Another technique related to primitive parameters being used as Method Parameters is called Preserve Whole Object. Consider the following code.

 

var employeeID = employeeInstance.GetEmployeeID();
var employeeDepartment = employeeInstance.GetDepartment();
var employeePaymentDetails = payment.GetPaymentDetails(employeeID, employeeDepartment);

 

Instead of calculating individual fields like employeeID and employeeDepartment, and then passing it to the GetPaymentDetails method, you could pass the employeeInstance object instead. This works in treating Long Methods  as  well.

 

The advantages of staying away from the Primitive Obsession include increased flexibility of code and well organized code. You have centralized place to maintain operations and conditions related to the particular data type. Also, it becomes easier for a future developer who doesn’t have to spend time guessing the limits/conditions related a particular data type.

 

Long Parameter List

How often have we ended up working with Methods which require more than 5 parameters ? Even harder would be existing code which utilizes a method which has many parameters. Remember, developers spend a better part of their development time reading existing code rather than creating a new one. So the implication of not writing easily readable code is quite large.  At least with .Net we do have Named Parameters which increases the readability a bit but at the end of the day, a method with 3 or 4 parameter is always easier to work with than one with 5-8 parameters. Ideally, anything more than 3 parameters for a method is a good candidate for refactoring.

 

So what are the effective refactoring techniques that could treat this particular kind of Code Smells.  We  have already discussed two earlier in this very blog post – Introduce Parameter Object and Preserve Whole Object. These two methods are effective in reducing the number of parameters used in a method.

 

A third technique, known as Replace Parameter with Method Call involves something similar. Consider the following code.

 

var employeeID = employeeInstance.GetEmployeeID();
var employeeDepartment = employeeInstance.GetDepartment();
var employeePaymentDetails = payment.GetPaymentDetails(employeeID, employeeDepartment);

 

Instead of the above code, where the daysWorked is calculated and passed to CalculateIncentive Method, we could have the CalculateIncentive method do the call to GetDaysWorked within itself, rather than being send as a Parameter. This would get rid of the parameter and simplify the method call.

 

Data Clumps

Another common bloater found in code is known as Data Clumps. Martin Fowler has coined the term as follows

 

“Whenever two or three values are gathered together, turn them into a $%#$%#^ object” – Martin Fowler

 

At times, you see a set of variables hanging around in groups in different part of the code. These are potential to be made into an object of their own.  If the group of variables are instance variable in class, then Extract Class is a good technique to apply. There might be other scenarios where the group of variables are as parameters of method, which gives us the option to employ Introduce Parameter Object and Preserve Whole Object.

 

Treating Data Clumps goes a long way in organizing code in a better way.

Code Smells : Bloaters (Long Methods, Long Class)

Code Bloats or Code Bloaters are probably the most common signs of code smells you can see in any branch of code. In fact, eradicating bloaters act as the first step towards refactoring your code. Bloaters are nothing but classes or methods that have grown excessively over a long time marking it difficult to work with. Typically, bloaters doesn’t happen right away, but is accumulate long term as your code base grows.

In this blog post, we will be discussing two of the most common bloaters, Long Method and Long Class

Long Methods

It is recommended that any method which is longer than 10 lines of code is a good candidate for refactoring. One could Extract Code Fragments (that does a specific task and relates to each other than any other piece of code in the method) that can be grouped together to a new Method (Extract Method), even if the new method is hardly couple of lines. It could also help in reducing code duplication and isolating independent parts of code.

Another refactoring technique that could be applied for Long Methods is Separating Query from Modifiers . It would be better to segregate the code fetching data from that modifies/mutates a state. The crux of this technique is based on the Command Query Seperation (CQS) Principle. CQS recommends dividing an object’s method into two broad categories, Queries (Returns a result, but doesn’t change any observable state) and Commands (changes observable state but doesn’t return a value). An observable state of an object is a state which can be accessed by the client code. However, care should be taken to avoid race condition that comes along the CQS approach in a multi-threaded application.

There might be certain scenario’s as well where the local variables are so intertwined with the code that it becomes difficult to extract method. In such scenarios, it might be a good idea to Replace Method with a Method Object, or in other words separate the Long Method into a Separate class, where the local variables of the class becomes Fields variables of the new class. Then it becomes much easier to split the method to smaller chunks of code.

Conditional Operators such as If-else or Switch Cases is another place where you could cut down the Method. You could either opt for refactoring techniques such as Decompose Conditional or use Strategy Pattern. Usage of Strategy Pattern also helps in bringing down the Cyclomatic Complexity of the Method.

Large Class

Large Class, similar to Long Methods are another undesired quality accumulated over time. Developers find it more convenient to add methods to existing classes than creating a new one. This results in Classes which cluttered with large number of methods and fields.

It is always better to split up a large class (Extract Class), especially if it has more than one responsibility. This ensures the class aligns with Single Responsibility Principle. There might be other cases where , there might be a class which utilizes a subset of its feature only in certain special scenarios. For Example consider the following code.

public class Person
{

void PublishMarks()
{
if(PersonType == PersonType.Student)
{
// Do Something
}
}

void PublishSalary()
{
if(PersonType == PersonType.Faculty)
{
// Do Something
}
}

}

In the above class, despite being related to the Person Class and sharing many other features with it, methods PublishMarks and PublishSalary are used only when the PersonType is Student or Faculty respectively. In this scenario, separating an entirely new Class for Student and Faculty isn’t quite recommended. Instead, we could take advantages of Inheritence and creates subclasses of Person Class, separating the Student and Faculty functionalities to SubClass. This technique is refactoring is known as Extracting SubClass.

Another scenario that is worth mentioning is cases when Domain (Business) Logic and Data gets embedded in the UI (Presentation) class. Problem with this approach is that you might end up with lot of duplicate code as the same domain objects might be required at other places in Presentation Classes. The refactoring technique, Duplicate Observed Data, recommends to remove Domain Data to separate classes and use an Observer pattern to synchronize the classes.

In the next of this series, we will look into few more Bloaters, including Primitive Obsession, Long Parameter List and Data Clumps.

References :
https://refactoring.com/catalog/
https://sourcemaking.com/