Home > Java > javaTutorial > ommon Code Smells in Java and How to Fix Them

ommon Code Smells in Java and How to Fix Them

Patricia Arquette
Release: 2025-01-22 18:05:14
Original
999 people have browsed it

ommon Code Smells in Java and How to Fix Them

Code smells signal potential problems in your Java code, impacting maintainability, readability, and performance. While not always bugs, addressing them keeps your codebase clean and efficient. This article examines five common Java code smells, providing examples, explanations, and improved solutions.


  1. Overly Long Methods

The Problem: Excessively long methods hinder readability, testing, and maintenance. Even with helper methods, combining multiple abstraction levels violates the Single Responsibility Principle (SRP).

Example:

<code class="language-java">public void processOrder(Order order) {
    validateOrder(order);
    calculateDiscount(order);
    updateInventory(order);
    generateInvoice(order);
    sendNotification(order);
}</code>
Copy after login
Copy after login

processOrder mixes unrelated tasks (validation, discount calculation, inventory updates, invoicing, and notifications), making it hard to modify without unintended consequences.

Solution: Refactor into smaller, focused methods. Design patterns like the Command Pattern or Pipeline Pattern enhance modularity.

Refactored Code (Command Pattern):

<code class="language-java">interface OrderCommand { void execute(Order order); }

class ValidateOrderCommand implements OrderCommand {
    public void execute(Order order) { /* Validation logic */ }
}

// ... other commands (ApplyDiscountCommand, etc.)

class OrderProcessor {
    List<OrderCommand> commands;

    public OrderProcessor(List<OrderCommand> commands) { this.commands = commands; }

    public void processOrder(Order order) {
        for (OrderCommand command : commands) { command.execute(order); }
    }
}

// Usage
List<OrderCommand> commands = List.of(new ValidateOrderCommand(), new ApplyDiscountCommand(), ...);
OrderProcessor processor = new OrderProcessor(commands);
processor.processOrder(new Order());</code>
Copy after login
Copy after login

Benefits: Improved modularity, independent testing and reuse of commands, easy addition of new steps.


  1. God Classes

The Problem: A "God Class" handles too many responsibilities, leading to high coupling and poor maintainability.

Example:

<code class="language-java">public class OrderManager {
    public void createOrder() { /* Implementation */ }
    public void updateOrder() { /* Implementation */ }
    public void deleteOrder() { /* Implementation */ }
    public void validatePayment() { /* Implementation */ }
    public void sendInvoice() { /* Implementation */ }
}</code>
Copy after login

Solution: Decouple responsibilities into smaller, focused classes.

Refactored Code:

<code class="language-java">public class OrderService {
    public void createOrder() { /* Implementation */ }
    // ... other order-related methods
}

public class PaymentService {
    public void validatePayment() { /* Implementation */ }
}

public class NotificationService {
    public void sendInvoice() { /* Implementation */ }
}</code>
Copy after login

Benefits: Reduced coupling, improved modularity, easier maintenance, testing, and independent extension.


  1. Magic Numbers

The Problem: Using literal numbers directly reduces code clarity and makes modifications risky.

Example:

<code class="language-java">public double calculateDiscount(double totalAmount) {
    return totalAmount > 1000 ? totalAmount * 0.1 : totalAmount;
}</code>
Copy after login

Solution: Replace literal numbers with named constants.

Refactored Code:

<code class="language-java">private static final double DISCOUNT_THRESHOLD = 1000;
private static final double DISCOUNT_RATE = 0.1;

public double calculateDiscount(double totalAmount) {
    return totalAmount > DISCOUNT_THRESHOLD ? totalAmount * DISCOUNT_RATE : totalAmount;
}</code>
Copy after login

Benefits: Enhanced readability, reduced error risk during updates, clearer business logic.


  1. Duplicate Code

The Problem: Repeated code across methods or classes leads to inconsistencies and maintenance headaches.

Example:

<code class="language-java">public double calculateTax(double amount) { return amount * 0.18; }
public double calculateDiscount(double amount) { return amount * 0.1; }</code>
Copy after login

Solution: Abstract common logic into a reusable method.

Refactored Code:

<code class="language-java">private double applyRate(double amount, double rate) { return amount * rate; }

public double calculateTax(double amount) { return applyRate(amount, 0.18); }
public double calculateDiscount(double amount) { return applyRate(amount, 0.1); }</code>
Copy after login

Benefits: Eliminates redundancy, ensures consistency, simplifies modification and extension.


  1. Excessive Parameter Lists

The Problem: Methods with many parameters are hard to read, understand, and prone to errors during calls.

Example:

<code class="language-java">public void processOrder(Order order) {
    validateOrder(order);
    calculateDiscount(order);
    updateInventory(order);
    generateInvoice(order);
    sendNotification(order);
}</code>
Copy after login
Copy after login

Solution: Encapsulate parameters within an object or use a builder pattern.

Refactored Code:

<code class="language-java">interface OrderCommand { void execute(Order order); }

class ValidateOrderCommand implements OrderCommand {
    public void execute(Order order) { /* Validation logic */ }
}

// ... other commands (ApplyDiscountCommand, etc.)

class OrderProcessor {
    List<OrderCommand> commands;

    public OrderProcessor(List<OrderCommand> commands) { this.commands = commands; }

    public void processOrder(Order order) {
        for (OrderCommand command : commands) { command.execute(order); }
    }
}

// Usage
List<OrderCommand> commands = List.of(new ValidateOrderCommand(), new ApplyDiscountCommand(), ...);
OrderProcessor processor = new OrderProcessor(commands);
processor.processOrder(new Order());</code>
Copy after login
Copy after login

Benefits: Improves readability and extensibility; adding parameters doesn't require method signature changes.


Addressing code smells proactively prevents larger design issues and reduces technical debt, leading to more robust and maintainable Java applications. Remember the principles of DRY (Don't Repeat Yourself) and SRP (Single Responsibility Principle) for cleaner, more efficient code.

The above is the detailed content of ommon Code Smells in Java and How to Fix Them. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template