Fundamentals 16 min read

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

The article explains why maintaining clean code is essential, covering naming conventions, class design, function principles, and testing strategies, and provides concrete Java examples and refactoring techniques to help developers write readable, maintainable, and high‑quality software.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Clean Code Practices: Naming, Classes, Functions, and Testing Guidelines

1. Why Keep Code Clean?

Unclean code accumulates over time, reducing productivity and causing problems such as hard‑to‑extend code, program crashes, overtime work, and increased company costs that can even lead to failure.

1.1 Start Clean from the Beginning

Write clean code from the start and refactor any messy parts immediately; never postpone improvements.

later equal never

1.2 How to Write Clean Code?

Clean code should be highly readable, avoid duplication, and adhere to design‑pattern principles including Single Responsibility, Open‑Closed, Liskov Substitution, Dependency Inversion, Interface Segregation, and Demeter.

2. Naming

Good naming improves readability, reduces understanding cost, and boosts efficiency.

2.1 Bad Naming Practices

Example of a meaningless method name:

public interface Animal {
    void abc();
}

Improved version with a meaningful name:

public interface Animal {
    void cry();
}

2.2 Inconsistent Naming

Inconsistent method names cause confusion. Standardize them, e.g., use findOneById and findAll consistently.

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

2.3 Redundant Naming

Avoid unnecessary words in names; use clear prefixes like getXxx() for single objects and listXxx() for collections.

// get a single object
getUser();
// get multiple objects
listUsers();

3. Classes

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

3.1 Single Responsibility

Each class should have only one reason to change, reducing complexity and improving maintainability.

3.2 Open‑Closed Principle

Classes should be open for extension but closed for modification. Refactor by extracting new responsibilities into subclasses.

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

3.3 Cohesion

High cohesion means methods and variables work together as a logical whole; split low‑cohesion classes into smaller, focused ones.

4. Functions

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

4.1 Do One Thing

Refactor long functions into smaller steps:

public String upload() {
    // validate image
    check();
    // compress image
    compress();
    return "0"; // success flag
}

4.2 Function Naming

Names should be descriptive. Bad example:

public String addCharacter(String originString, char ch);

Better examples:

// append to the end
public String appendCharacter(String originString, char ch);
// insert at a specific position
public String insertCharacter(String originString, char ch, int position);

4.3 Parameters

Keep parameters minimal; encapsulate related data into objects when there are many.

// before
public List
findStudent(int age, String name, String country, int gender);
// after
public List
findStudent(StudentCriteria criteria);

4.4 Return Values

Separate commands from queries and use exceptions instead of error codes.

public void addElement(Element e) { /* command */ }
public boolean isAdd(Element e) { /* query */ }

5. Testing

Testing validates code correctness and should also be clean.

5.1 TDD (Test‑Driven Development)

Write failing tests before implementation, then develop just enough code to pass them.

5.2 FIRST Principles

Fast – tests run quickly.

Independent – tests do not depend on each other.

Repeatable – tests produce the same result every time.

Self‑validating – tests assert outcomes automatically.

Timely – tests are written before production code.

5.3 Given‑When‑Then Pattern

@Test
public void shouldReturnItemNameInUpperCase() {
    // Given
    Item mockedItem = new Item("it1", "Item 1", "Desc", 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 Automatic Test Generation

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

6. Conclusion

Writing clean code improves readability, maintainability, and extensibility, and using tools like SonarLint helps quantify and enforce code quality.

testingrefactoringclean codenaming-conventionssingle responsibility
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

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.