Code Smell Bloater’s Exercise

Code Smell Bloater’s Exercise

Vineet Sharma
3 min readMar 7, 2024

Code smells are indicators of poor code design that can lead to potential issues such as reduced maintainability, increased complexity, and decreased scalability. Blotter’s Exercise, a fictional scenario, serves as an example to identify and refactor code smells in a .NET Core project.

In this guide, we will delve into the Blotter’s Exercise source code, identify various code smells, and step-by-step refactor the code to improve its quality and maintainability.

using System;
using System.Collections.Generic;

namespace BlottersExercise
{
public class TaskManager
{
private List<Task> tasks;

public TaskManager()
{
tasks = new List<Task>();
}

public void AddTask(Task task)
{
tasks.Add(task);
}

public void UpdateTask(int index, Task updatedTask)
{
if (index >= 0 && index < tasks.Count)
{
tasks[index] = updatedTask;
}
else
{
Console.WriteLine("Invalid index.");
}
}

public void DeleteTask(int index)
{
if (index >= 0 && index < tasks.Count)
{
tasks.RemoveAt(index);
}
else
{
Console.WriteLine("Invalid index.");
}
}

public void PrintTasks()
{
foreach (var task in tasks)
{
Console.WriteLine(task.ToString());
}
}
}

public class Task
{
public string Description { get; set; }
public bool IsCompleted { get; set; }

public override string ToString()
{
return $"Description: {Description}, Completed: {IsCompleted}";
}
}

class Program
{
static void Main(string[] args)
{
TaskManager taskManager = new TaskManager();

taskManager.AddTask(new Task { Description = "Write blog post", IsCompleted = false });
taskManager.AddTask(new Task { Description = "Refactor source code", IsCompleted = false });
taskManager.AddTask(new Task { Description = "Run unit tests", IsCompleted = true });

taskManager.PrintTasks();
}
}
}

Identify some common code smells present in this code:

  1. Duplicated Code: The validation logic in UpdateTask and DeleteTask methods is duplicated.
  2. Long Methods: The PrintTasks method contains logic for printing tasks and is relatively long.
  3. Primitive Obsession: The Task class uses primitive data types (string and bool) directly for task properties, which can lead to limited functionality and maintainability.
  4. Inadequate Error Handling: Error handling in the UpdateTask and DeleteTask methods is insufficient.
  5. Violation of Single Responsibility Principle (SRP): The TaskManager class handles both managing tasks and printing them, violating SRP.

Let’s refactor this code to address these code smells:

using System;
using System.Collections.Generic;

namespace BlottersExercise
{
public class TaskManager
{
private List<Task> tasks;

public TaskManager()
{
tasks = new List<Task>();
}

public void AddTask(Task task)
{
tasks.Add(task);
}

public void UpdateTask(int index, Task updatedTask)
{
if (IsValidIndex(index))
{
tasks[index] = updatedTask;
}
else
{
Console.WriteLine("Invalid index.");
}
}

public void DeleteTask(int index)
{
if (IsValidIndex(index))
{
tasks.RemoveAt(index);
}
else
{
Console.WriteLine("Invalid index.");
}
}

private bool IsValidIndex(int index)
{
return index >= 0 && index < tasks.Count;
}

public void PrintTasks()
{
foreach (var task in tasks)
{
Console.WriteLine(task.ToString());
}
}
}

public class Task
{
public string Description { get; set; }
public bool IsCompleted { get; set; }

public override string ToString()
{
return $"Description: {Description}, Completed: {IsCompleted}";
}
}

class Program
{
static void Main(string[] args)
{
TaskManager taskManager = new TaskManager();

taskManager.AddTask(new Task { Description = "Write blog post", IsCompleted = false });
taskManager.AddTask(new Task { Description = "Refactor source code", IsCompleted = false });
taskManager.AddTask(new Task { Description = "Run unit tests", IsCompleted = true });

taskManager.PrintTasks();
}
}
}

In this refactored version, we’ve addressed the identified code smells:

  1. Duplicated code is eliminated by extracting the validation logic into a separate private method IsValidIndex.
  2. The PrintTasks method remains unchanged for simplicity, but in a real-world scenario, it might be refactored further.
  3. We haven’t addressed the Primitive Obsession smell in this example, but it could be improved by encapsulating task properties within a separate class.
  4. Error handling is improved by validating index values before performing update or delete operations.
  5. We haven’t addressed the SRP violation in this example, but separating concerns further might involve creating a separate class responsible for printing tasks.

Refactoring code in this manner improves readability, maintainability, and reduces the likelihood of introducing bugs in the future.

The source code is available at https://gitlab.com/mvineetsharma/Workshop/Exercise/codesmellbloatersexercise.git

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response