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/

SOLID : Single Responsibility Principle

While OOPs is rich with features like inheritance, polymorphism, encapsulation and overloading enabling developers to extract more from modern day programming languages like C#, it is equally important to understand when to use these features based on design principles.

SOLID, is a set of 5 principles which when properly applied intend to guide a programmer to make systems that is scalable and maintainable with ease.

The first of SOLID Principles, (S) – Single Responsibility Principle (SRP) demands that a class should have only a single responsibility and that responsibility should be fully encapsulated by that a class.

Consider the following class. The class is intended to Book Movie Tickets.

image

If you observe the class, the method BookTicket is divided into two parts. First, it books the tickets and then it notify the User about the same. That is, the class has two responsibilities – Book Tickets and Notify User, in other words, there are two reasons for which the class can be changed.

Suppose few years later, the company decides to change the notification mechanism and include SMS support as well. This would mean our MovieTicket Class needs to be altered for a reason (user notification), which has nothing to do with the core functionality of the class (booking ticket).

This is violation of SRP and the obvious solution would be to separate the responsibilities to separate classes.

image

This ensures that each class has only one responsibility and there would be only reason to change it.