Clean Code Practices: Naming, Classes, Functions, and Testing Guidelines
This article explains why clean code matters and provides practical guidelines on naming, class design, function decomposition, SOLID principles, testing strategies such as TDD and FIRST, as well as tooling like SonarLint to improve code quality and maintainability.
1. Why Keep Code Clean?
Unclean code reduces productivity over time, leads to difficult extensions, crashes, overtime, and increased company costs; in extreme cases it can even cause a project or company to fail.
1.1 Start Clean from the Beginning
Write clean code from day one and refactor any messy parts immediately; procrastinating on cleanup only makes the problem worse.
later equal never1.2 How to Write Clean Code?
High readability – code should read like prose.
Avoid duplicated code.
Follow design‑pattern principles (SOLID): Single Responsibility Open‑Closed Liskov Substitution Dependency Inversion Interface Segregation Law of Demeter Composition over Inheritance
2. Naming
Good names increase readability, reduce understanding cost and overtime.
2.1 Bad Naming Example
public interface Animal {
void abc();
}The method name abc gives no clue about its purpose.
2.2 Meaningful Naming
public interface Animal {
void cry();
}Now callers understand the method performs a "cry" action.
2.3 Inconsistent Naming
public interface StudentRepository extends JpaRepository<AlertAll, String> {
Student findOneById(@Param("id") String id);
List<Student> queryAllStudent();
}Rename to keep consistency:
public interface StudentRepository extends JpaRepository<AlertAll, String> {
Student findOneById(@Param("id") String id);
List<Student> findAll();
}2.4 Redundant Naming
// Get a single object
getXxx();
// Get multiple objects
listXxxx();3. Classes
A clean class should satisfy:
Single Responsibility
Open‑Closed
High Cohesion
3.1 Single Responsibility
Classes should be small and have only one reason to change. Large classes usually violate this principle.
public abstract class Sql {
// SQL operation
public abstract void insert();
// Statistics operation
public abstract void countInsert();
}Refactor by extracting the statistics part:
public abstract class CountSql {
public abstract void countInsert();
}3.2 Open‑Closed Principle
Code should be open for extension but closed for modification. Example of violation:
public abstract class Sql {
public abstract void insert();
public abstract void update();
public abstract void delete();
}After refactoring:
public abstract class Sql {
public abstract void generate();
}
public class CreateSql extends Sql {
@Override
public void generate() { /* implementation */ }
}4. Functions
Clean functions should:
Do one thing only.
Have descriptive names.
Use clean parameters.
Return appropriate results.
4.1 One Thing Only
public class PicService {
public String upload(){
// validation (80 lines)
// compression (50 lines)
return "0";
}
}Refactor into smaller steps:
public String upload(){
check();
compress();
return "0";
}4.2 Function Naming
Bad example:
public String addCharacter(String originString, char ch);Better examples:
// append to end
public String appendCharacter(String originString, char ch);
// insert at position
public String insertCharacter(String originString, char ch, int insertPosition);4.3 Parameters
Prefer few parameters; if more than three, encapsulate them.
public List<Student> findStudent(int age, String name, String country, int gender);
// after encapsulation
public List<Student> findStudent(Student student);Avoid Boolean flag parameters:
// bad
render(Boolean isSuite);
// good
renderForSuite();
renderForSingleTest();4.4 Return Values
Separate commands from queries:
// bad
public Boolean addElement(Element element);
// good
public void addElement(Element element);
public Boolean isAdd(Element element);Prefer exceptions over error‑code returns.
// error‑code style (complex nesting)
if(handle!=DeviceHandle.INVALID){…}
else{…}
// exception style
try{…}catch(DeviceShutDownError e){…}5. Testing
Testing validates code correctness; test code should also be clean.
5.1 TDD
Test‑Driven Development writes a failing test first, then production code to make it pass.
Fast execution.
Independent tests.
Repeatable.
Self‑validating.
Timely (written before code).
5.2 FIRST Principle
Fast
Independent
Repeatable
Self‑validating
Timely
5.3 Test Code Pattern
Use the given‑when‑then structure:
@Test
public void shouldReturnItemNameInUpperCase(){
// Given
Item mockedItem = new Item("it1","Item 1",…);
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 Automated Test Generation
IDEA plugins such as Squaretest (paid) and TestMe (free) can generate unit tests automatically.
6. Tooling
SonarLint helps discover code smells, duplicated code, potential NPEs, and suggests fixes, making metrics like bug rate and duplication rate measurable.
7. Conclusion
Writing clean code improves readability, extensibility, development efficiency, reduces overtime, and raises the developer’s skill level; everyone should read "Clean Code" and apply these principles from the start.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.