Saturday, September 30, 2023

Common Code Smells and Heuristics

 


Before we start learning about code issues, improvements, and rules, let’s see how many IT professionals worldwide rely on code, whether they write it themselves or not (like managers, for example).

As per some stats:

  • There are an estimated 26.9 million professional software engineers in the world as of 2022
  • There are nearly 27 million developers worldwide. This number is expected to exceed 28.7 million by 2024
  • According to industry research firm Janco Associates, more than 4.18 million people are employed as IT professionals in the US

Now, we will go through the section wise code smells and heuristics.


Comments:

Inappropriate information: Don’t put info in comments that should be in other systems like source code control or issue tracking. Comments are for technical notes about the code and design, not for things like change histories or metadata.

/**
* Author: Jane Doe
* Last Modified: 2022-04-20
* Version: 1.2
* Description: This class represents a basic calculator.
* Change History:
* - Version 1.0: Initial implementation
* - Version 1.1: Fixed a bug in the add() method
* - Version 1.2: Added support for subtraction
*/

public class Calculator {

// Calculate the sum of two numbers
public int add(int a, int b) {
return a + b;
}

// Calculate the difference between two numbers
public int subtract(int a, int b) {
return a - b;
}
}

In the text above, it’s saying that the information about changes, history, and when something was last modified is written in a comment. But this information isn’t necessary because it’s already stored in a source code control system like Git.

Cleaner version:

/**
* This class represents a basic calculator.
*/

public class Calculator {

// Calculate the sum of two numbers
public int add(int a, int b) {
return a + b;
}

// Calculate the difference between two numbers
public int subtract(int a, int b) {
return a - b;
}
}

Obsolete comment: Obsolete comments, being outdated, should be avoided. Remove or update them promptly to prevent confusion. Sometime we change the code but not the comments :)

public class ObsoleteCommentsExample {

// Calculate the sum of two numbers
public int add(int a, int b) {
return a + b;
}

// Author: John Smith
// Last Modified: 2020-12-05
// This method is used to add two numbers.
// Change History:
// - Version 1.0: Initial implementation
// - Version 1.1: Fixed a bug in the addition logic (Obsolete)
public int addObsolete(int a, int b) {
// Obsolete comment: The bug was fixed in version 1.1, but the comment was not updated.
return a + b;
}

// Calculate the difference between two numbers
public int subtract(int a, int b) {
return a - b;
}

// Description: This method subtracts two numbers.
// Change History:
// - Version 1.0: Initial implementation
public int subtractObsolete(int a, int b) {
// Obsolete comment: The comment contains unnecessary information and is outdated.
return a - b;
}
}

Redundant comment: A comment is redundant if it describes something that adequately describes itself.

 i++; // increment i

Comments should say things that the code cannot say for itself, example:

 /**
* @param sellRequest
* @return
* @throws ManagedComponentException
*/

public SellResponse beginSellItem(SellRequest sellRequest)
throws ManagedComponentException

Poorly Written Comment: A well-written comment is a valuable addition. When you choose to include a comment, take the opportunity to create a high-quality one. Pay attention to word choice, maintain proper grammar and punctuation, avoid excessive elaboration, and keep it succinct.

public class PoorCommentExample {

// This is a function that adds two numbers
public int addition(int num1, int num2) {
// Here, we add num1 and num2 together
int result = num1 + num2; // The result is stored in the result variable
return result; // We return the result
}
}
public class CommentQualityExample {

// This method calculates the sum of two numbers.
// It takes two integers as input and returns their sum.
public int add(int a, int b) {
// Here, we add the two numbers and store the result in 'sum'.
int sum = a + b;

// Finally, we return the 'sum' as the result of the addition.
return sum;
}

// This method finds the difference between two numbers.
// It subtracts 'b' from 'a' and returns the result.
public int subtract(int a, int b) {
// To calculate the difference, we subtract 'b' from 'a'.
int difference = a - b;

// We then return the 'difference' as the result.
return difference;
}

// This method multiplies two numbers.
public int multiply(int a, int b) {
// Multiply 'a' and 'b' to get the result.
int result = a * b;

// Return the 'result'.
return result;
}
}

Commented out code: This issue frequently arises during code reviews. When questioned, developers often offer excuses like “someone else did it” or “we might need it later.” However, as a firm guideline, it’s best to eliminate commented-out code. You can always retrieve it from the version control system when necessary.

public class CommentedCodeExample {

public static void main(String[] args) {
int x = 5;
int y = 10;

// int result = x + y;
// System.out.println("The sum is: " + result);

// The code below is no longer needed.
// It was used for an earlier feature that has been removed.
// int z = 20;
// int finalResult = result + z;
// System.out.println("The final result is: " + finalResult);
}
}

Environment:

Build Requires More Than One Step: Starting a project should be easy. You shouldn’t need to fetch many code pieces, use complex commands, or hunt for extra files. Just one command to check out the system and one more to build it should suffice.

# Before applying simplification heuristic
git clone <repository-url>
cd project
./setup.sh
./build.sh
# Manually find and copy required JAR files
# Search for and configure XML files from different directories
# After applying simplification heuristic
git clone <repository-url>
./build.sh

Tests Require More Than One Step: Running all unit tests should be simple. You should be able to do it with one click in your IDE or with a single command in your shell. It’s a fundamental and essential task, so it should be quick and easy.

# Before streamlining testing
cd project-directory
./setup-environment.sh
./run-unit-tests.sh
# After streamlining testing
cd project-directory
./run-tests.sh

Functions:

Too Many Arguments: Functions are most effective when they accept a modest number of arguments. The ideal scenario is having zero arguments, followed by one, two, and three. If a function has more than three arguments, it becomes problematic and should be minimized whenever possible. This is because an excessive number of arguments often indicates that the function is handling multiple tasks, which goes against the Single Responsibility Principle (SRP).

public double calculateTotalPrice(double item1, double item2, double item3, double item4, double item5, double item6) {
double total = item1 + item2 + item3 + item4 + item5 + item6;
return total;
}
public double calculateTotalPrice(double[] items) {
double total = 0.0;
for (double item : items) {
total += item;
}
return total;
}

Output Arguments: Output arguments can be confusing. People usually think of arguments as things you put into a function, not things that come out of it. If your function needs to modify something, it’s better to have it change the thing it’s working on, like an object it’s called on.

public void appendToList(int item, List<Integer> outputList) {
// Try to add the item to the output list
outputList.add(item);
}
public List<Integer> createNewListWithItem(int item, List<Integer> inputList) {
List<Integer> newList = new ArrayList<>(inputList);
newList.add(item);
return newList;
}

Flag Arguments: When a method takes a flag as an argument, it often suggests an attempt to perform multiple tasks within the same method. This typically requires the use of conditional statements (if/else) to determine which task to execute.

public double calculateTotalPrice(List<Item> items, boolean applyDiscount) {
double totalPrice = 0.0;

for (Item item : items) {
if (applyDiscount) {
totalPrice += item.getDiscountedPrice();
} else {
totalPrice += item.getPrice();
}
}

return totalPrice;
}
public double calculateTotalPriceWithDiscount(List<Item> items) {
double totalPrice = 0.0;

for (Item item : items) {
totalPrice += item.getDiscountedPrice();
}

return totalPrice;
}

public double calculateTotalPriceWithoutDiscount(List<Item> items) {
double totalPrice = 0.0;

for (Item item : items) {
totalPrice += item.getPrice();
}

return totalPrice;
}

Dead Function: A method that is never called in any part of the code should be promptly removed from the codebase.

public class Calculator {
public int add(int a, int b) {
return a + b;
}

// This method is never called
public int subtract(int a, int b) {
return a - b;
}
}
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
  • Code coverage tools like JaCoCo (for Java), Istanbul (for JavaScript), and Coverage.py (for Python) can help identify code that is not executed by tests, which often indicates dead code.
  • SonarQube: SonarQube is a widely used code quality platform that can identify dead code and provide detailed reports on code quality.
  • FindBugs: FindBugs is a static analysis tool for Java that can detect various issues, including dead code.
  • ESLint and TSLint: For JavaScript and TypeScript projects, ESLint and TSLint can identify unused variables and functions.

More: https://ajhawrites.medium.com/common-code-smells-and-heuristics-fd7e15a8a602

Saturday, September 16, 2023

Inspiring Success: The Art of Leadership Styles and Human Dynamics

 

Photo by Markus Spiske on Unsplash

Leadership is a skill that you can’t fully learn from school or a course. However, we can teach you some important principles and tell you about the different leadership styles that are well-known or not well-liked.

It’s up to individuals to understand and use a specific leadership style depending on the situation. There’s no one-size-fits-all approach, so they need to choose the right style for each circumstance.

Managing humans is indeed different from managing machines or robots because it’s much more complex. This is because understanding human psychology can be very challenging. It requires a lot of patience, empathy, and a strong connection to truly understand someone.

In my experience as a leader, I’ve had the opportunity to lead teams of various sizes, and I’ve noticed that team members often fall into different categories or types:

Fruits eater: These team members fall into the category of “Free Riders.” They tend to benefit from the efforts of others but contribute little or negatively impact the team’s overall success.

Silent Quitter: These individuals may appear quiet and disengaged, but they may be feeling disheartened or disconnected from the team, which can affect their overall performance and morale.

Rock Stars: These individuals consistently shine and excel in their roles, making significant positive contributions to the team’s success. They are the standouts in the group.

Silent worker: These individuals may not seek the spotlight or vocalize their efforts, but they consistently contribute effectively to the team’s goals through their diligent and dedicated work.

Political Pandits: These individuals are skilled at navigating office politics and using their influence within the organization to advance their agendas. They often excel in the political aspects of the workplace.

Gyaani Gurus: These individuals often consider themselves as experts on various topics and are eager to share their knowledge and insights with others, sometimes even when it’s not requested. They can be valuable sources of information but may sometimes overdo it.

Conflicters: These individuals tend to frequently engage in conflicts or disagreements with others in the team. They may have strong opinions and often express them in a confrontational manner, which can create tension within the team. Managing conflicts with such team members can be challenging but important for team cohesion.

There are several other types that we won’t be discussing here. Therefore, to effectively manage these various team member types, whether within a team or across teams, it’s crucial to apply the appropriate leadership style that suits the specific situation or people involved.

In the following section, we will explore various leadership styles.


Autocratic Leadership: In this approach, the leader makes all decisions without involving the team. They have full control and assign tasks without input from team members. After decisions are made, everyone is expected to agree, which can make the team uncomfortable about the leader’s authority.

This leadership style is essential in situations like the military, where national security is at stake and quick decisions are crucial for life and death scenarios.

However, using this style everywhere isn’t recommended. It can harm team productivity and motivation, so it’s important to apply it selectively.

Democratic Leadership: In this approach of leadership, the leader wants everyone to join in making decisions. They don’t decide everything alone. They ask team members for their ideas and thoughts. This makes the team work together, includes everyone, and makes people feel like it’s their team too. The leader believes that the group’s ideas are better than just one person’s.

Servant Leadership: In this approach of leadership, a leader focuses on serving and helping their team members. They put their team’s needs before their own. This style is about supporting and empowering the team to succeed. It creates a positive and cooperative work environment.

Transformational Leadership: In this approach of leadership, a leader emphasis on inspiring and motivating teams to achieve extraordinary results. Leaders who adopt this style are seen as visionary and able to create a shared sense of purpose. They often lead by example and encourage creativity and innovation.

Authentic Leadership: In this approach of leadership, genuine and transparent behavior from leaders are expected. It involves self-awareness, moral integrity, and the ability to build trust with team members. Authentic leaders are seen as credible and trustworthy, which can have a significant impact on team morale and performance.

Happy leading, “We don’t have to push people to succeed but to inspire them to succeed”.

LocalBaniya: Giving Every Small Shop in India a Digital Identity

  LocalBaniya: Giving Every Small Shop in India a Digital Identity More:  Localbaniya.shop