Fundamentals 17 min read

Mastering Clean Code: Design Principles, KISS, DRY, and Naming Best Practices

Learn how to write readable, maintainable, and reusable methods by applying core design principles such as Single Responsibility, KISS, and DRY, along with practical naming conventions, parameter handling, method size guidelines, and code structuring techniques illustrated with Java examples.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Mastering Clean Code: Design Principles, KISS, DRY, and Naming Best Practices

Design Principles

A good method should be readable, maintainable, and reusable. This article explains how to improve these qualities through design principles and coding standards, which can be applied not only to methods but also to classes and modules.

Single Responsibility Principle

A module should have only one responsibility, which improves maintainability and reusability. Example:

public boolean checkUsernameOrPassword(String str) {
    return str != null && str.length() > 5 && str.length() < 18;
}

If business requirements change, splitting the method into two single‑purpose methods avoids unintended side effects:

public boolean checkPassword(String password) {
    boolean checkLen = password != null && password.length() > 5 && password.length() < 18;
    return checkLen && (/* validate case and digits */);
}

public boolean checkUsername(String username) {
    return username != null && username.length() > 5 && username.length() < 18;
}

KISS Principle

Keep It Simple and Stupid means code should be simple to understand, not merely short. Two IP‑validation implementations illustrate this:

// Simple regex version
public boolean isValidIpAddressV1(String ipAddress) {
    if (StringUtils.isBlank(ipAddress)) return false;
    String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." +
        "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." +
        "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." +
        "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
    return ipAddress.matches(regex);
}

// Rule‑based version
public boolean isValidIpAddressV2(String ipAddress) {
    if (StringUtils.isBlank(ipAddress)) return false;
    String[] ipUnits = StringUtils.split(ipAddress, '.');
    if (ipUnits.length != 4) return false;
    for (int i = 0; i < 4; ++i) {
        int ipUnitIntValue;
        try { ipUnitIntValue = Integer.parseInt(ipUnits[i]); }
        catch (NumberFormatException e) { return false; }
        if (ipUnitIntValue < 0 || ipUnitIntValue > 255) return false;
        if (i == 0 && ipUnitIntValue == 0) return false;
    }
    return true;
}

The shorter regex version is not necessarily simpler; readability and maintainability matter more than line count.

DRY Principle

Don’t Repeat Yourself aims to avoid duplicated logic, semantics, or execution. Examples:

public boolean checkPassword(String password) {
    return password != null && password.length() > 6 && password.length() < 18;
}

public boolean checkUsername(String userName) {
    return userName != null && userName.length() > 6 && userName.length() < 18;
}

Although the logic is identical, the semantics differ, so merging them would violate the Single Responsibility Principle.

// Different implementations with same semantics (IP validation)
public boolean isValidIpAddressV1(String ipAddress) { /* regex version */ }
public boolean isValidIpAddressV2(String ipAddress) { /* rule‑based version */ }

Having two functions that do the same thing but with different logic can cause confusion and maintenance overhead.

Good Code Habits

Naming

Names should convey intent without being overly verbose. Use context to shorten names (e.g., getName instead of getUserName) and prefer consistent naming across the codebase.

Parameter Definition

Avoid more than four parameters; consider whether the method respects the Single Responsibility Principle or encapsulate parameters into an object. Choose between int and Integer based on nullability and requiredness.

Method Body

Keep methods within one screen height. Split long methods into logical blocks with comments, and avoid deep nesting by using early return or continue statements.

// Before refactoring
public void example(List<String> strList, String substr) {
    if (CollectionUtils.isNotEmpty(strList) && StringUtils.isNotBlank(substr)) {
        for (String str : strList) {
            if (str != null) {
                if (str.contains(substr)) {
                    // business logic
                } else {
                    // other logic
                }
            }
        }
    }
}

// After refactoring
public void example(List<String> strList, String substr) {
    if (CollectionUtils.isEmpty(strList) || StringUtils.isBlank(substr)) return;
    for (String str : strList) {
        if (str == null) continue;
        if (str.contains(substr)) {
            // business logic
        } else {
            // other logic
        }
    }
}

Comments

Use comments to clarify complex logic, but avoid over‑commenting; the code itself should be clear enough.

Reference books: "Design Patterns Explained" and "Refactoring".

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaclean codenaming conventionsdesign principlesDRYKISS
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

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.