Fundamentals 15 min read

Clean Code Practices: Naming, Classes, Functions, and Testing

This article explains why clean code matters and provides practical guidelines on naming, class design, function design, and testing—including principles, refactoring examples, and tool recommendations—to help developers write more readable, maintainable, and robust Java code.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Clean Code Practices: Naming, Classes, Functions, and Testing

1 Why Keep Code Clean?

Unclean code reduces productivity over time, leading to hard‑to‑extend code, program crashes, overtime, increased company costs, and even potential failure.

1.1 Start Clean from the Beginning

Write clean code from the start and refactor any messy parts immediately; avoid the mindset of fixing it later.

later equal never

1.2 What Makes Code Clean?

Clean code should be highly readable, avoid duplication, and follow design‑pattern principles such as Single Responsibility, Open‑Closed, Liskov Substitution, Dependency Inversion, Interface Segregation, Demeter, and Composite Reuse.

2 Naming

Good naming improves readability, reduces understanding cost, and lowers overtime.

2.1 Bad Naming Practices

Examples of meaningless names:

public interface Animal { void abc(); }

The method name abc gives no clue about its purpose.

Improved naming:

public interface Animal { void cry(); }

Now the purpose is clear.

2.2 Inconsistent Naming

Inconsistent method names cause confusion:

public interface StudentRepository extends JpaRepository
{
    Student findOneById(@Param("id") String id);
    List
queryAllStudent();
}

After standardising:

public interface StudentRepository extends JpaRepository
{
    Student findOneById(@Param("id") String id);
    List
findAll();
}

2.3 Redundant Naming

Avoid unnecessary words in names, e.g., using getXxx for single objects and listXxx for collections.

3 Classes

Clean classes should satisfy Single Responsibility, Open‑Closed, and high cohesion.

3.1 Single Responsibility

Classes should be small and have only one reason to change, reducing complexity and improving maintainability.

How to determine if a class is short enough?

If a class cannot be described by a precise name, it is likely too large.

Example of a class with multiple responsibilities:

public abstract class Sql {
    // operate SQL
    public abstract void insert();
    // count inserts
    public abstract void countInsert();
}

Refactored into two classes:

public abstract class Sql { public abstract void generate(); }
public class CreateSql extends Sql { @Override public void generate() { /* ... */ } }
public class UpdateSql extends Sql { @Override public void generate() { /* ... */ } }

3.2 Open‑Closed Principle

Code should be open for extension but closed for modification; adding new logic should not require changing existing classes.

3.3 Cohesion

High cohesion means methods and variables are tightly related, forming a logical whole.

4 Functions

Clean functions should do one thing, have good names, clean parameters, and clear return values.

4.1 Do One Thing

Before refactoring, a function may handle validation, compression, and result generation in one method:

public String upload() {
    // validate image (80 lines)
    // compress image (50 lines)
    // return status (5 lines)
    return "0";
}

After refactoring:

public String upload() {
    check();
    compress();
    return "0";
}

4.2 Function Naming

Names should be descriptive; for example, appendCharacter vs. addCharacter clarifies intent.

4.3 Parameters

Keep parameters few; encapsulate when exceeding three, and avoid Boolean flag parameters that hide multiple responsibilities.

4.4 Return Values

Separate commands from queries and prefer throwing exceptions over returning error codes.

4.5 Writing Such Functions

Write functional code first, then refactor immediately—"later equal never".

4.6 Code Quality Tools

Tools like SonarLint can detect issues such as duplicate code, potential NPEs, and suggest using LocalDate / LocalTime for dates.

5 Testing

Testing validates code correctness; test code should also be clean.

5.1 TDD

Test‑Driven Development encourages writing failing tests before production code, ensuring rapid feedback.

5.2 FIRST Principles

Tests should be Fast, Independent, Repeatable, Self‑validating, and Timely.

5.3 Test Code Patterns

Use the given‑when‑then pattern for readable tests.

/**
 * If an item is loaded from the repository, its name should be transformed to uppercase.
 */
@Test
public void shouldReturnItemNameInUpperCase() {
    // Given
    Item mockedItem = new Item("it1", "Item 1", "This is item 1", 2000, true);
    when(itemRepository.findById("it1")).thenReturn(mockedItem);
    // When
    String result = itemService.getItemNameUpperCase("it1");
    // Then
    verify(itemRepository, times(1)).findById("it1");
    assertThat(result, is("ITEM 1"));
}

5.4 Auto‑Generating Tests

IDEA plugins such as Squaretest (paid) and TestMe (free) can generate unit tests automatically.

References:

Book: <<代码整洁之道>>

https://www.cnblogs.com/sunny3158/p/16353643.html

https://blog.csdn.net/qq_42289636/article/details/108762981

Javatestingsoftware engineeringclean codeclass-designNamingfunction design
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.