Fundamentals 17 min read

Why Refactoring Matters: Lessons from "Refactoring" for New Engineers

The article reviews the book “Refactoring: Improving the Design of Existing Code”, explains what refactoring is, why it is essential for maintainability and efficiency, and presents practical techniques—such as removing duplicate code, improving naming, simplifying conditions, and using enums—to help engineers with one‑year experience write cleaner, more maintainable Java code.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
Why Refactoring Matters: Lessons from "Refactoring" for New Engineers
Book cover
Book cover

Preface

Long ago a senior teammate recommended the book Refactoring: Improving the Design of Existing Code . At first I skimmed it without much resonance because I had not yet worked with production code. After a year of engineering experience, I finally read the book thoroughly and gained many insights, which I now share with fellow engineers who have about a year of coding experience.

1. Definition of Refactoring

The book defines refactoring as a structural adjustment of software that improves understandability while preserving observable behavior.

My interpretation: Refactoring makes code cleaner and easier to understand without changing its external behavior, benefiting both machines and developers.

2. Why Refactor?

Key points from the book and personal experience:

Increase development efficiency: Readable code reduces the time spent understanding existing logic, especially under tight deadlines.

Reduce modification risk: Cleaner code lowers the chance of bugs when changes are made, which is crucial for stability‑focused companies.

3. Refactoring Practices

3.1 Reduce Duplicate Code

Duplicate code raises modification risk because a change must be applied in many places. Two ways to eliminate duplication are removing stale files and decreasing coupling by reusing single‑purpose methods.

Problem background: Repeated code increases reading cost for newcomers and creates inconsistency when modifications are missed.

public PhotoHomeInitRes photoHomeInit() {
    if (!photoDrm.inUserPhotoWhitelist(SessionUtil.getUserId())) {
        LoggerUtil.info(LOGGER, "[PhotoFacade] 用户暂无使用权限,userId=", SessionUtil.getUserId());
        throw new BizException(ResultEnum.NO_ACCESS_AUTH);
    }
    PhotoHomeInitRes res = new PhotoHomeInitRes();
    InnerRes innerRes = photoAppService.renderHomePage();
    res.setSuccess(true);
    res.setTemplateInfoList(innerRes.getTemplateInfoList());
    return res;
}

public CheckStorageRes checkStorage() {
    if (!photoDrm.inUserPhotoWhitelist(SessionUtil.getUserId())) {
        LoggerUtil.info(LOGGER, "[PhotoFacade] 用户暂无使用权限,userId=", SessionUtil.getUserId());
        throw new BizException(ResultEnum.NO_ACCESS_AUTH);
    }
    CheckStorageRes checkStorageRes = new CheckStorageRes();
    checkStorageRes.setCanSave(photoAppService.checkPhotoStorage(SessionUtil.getUserId()));
    checkStorageRes.setSuccess(true);
    return checkStorageRes;
}

After extracting the whitelist check into a common method, the code becomes shorter and less error‑prone:

public PhotoHomeInitRes photoHomeInit() {
    photoAppService.checkUserPhotoWhitelist(SessionUtil.getUserId());
    PhotoHomeInitRes res = new PhotoHomeInitRes();
    InnerRes innerRes = photoAppService.renderHomePage();
    res.setSuccess(true);
    res.setTemplateInfoList(innerRes.getTemplateInfoList());
    return res;
}

public CheckStorageRes checkStorage() {
    photoAppService.checkUserPhotoWhitelist(SessionUtil.getUserId());
    CheckStorageRes checkStorageRes = new CheckStorageRes();
    checkStorageRes.setCanSave(photoAppService.checkPhotoStorage(SessionUtil.getUserId()));
    checkStorageRes.setSuccess(true);
    return checkStorageRes;
}

public boolean checkUserPhotoWhitelist(String userId) {
    if (!photoDrm.openMainSwitchOn(userId) && !photoDrm.inUserPhotoWhitelist(userId)) {
        LoggerUtil.info(LOGGER, "[PhotoFacade] 用户暂无使用权限, userId=", userId);
        throw new BizException(ResultEnum.NO_ACCESS_AUTH);
    }
    return true;
}

3.2 Improve Readability

3.2.1 Effective Comments

Business‑level comments that explain *why* a piece of code exists are far more valuable than comments that merely restate *what* the code does.

// Generate voucher identifiers and fetch recommendation info
List<String> voucherMarkList = CommonUtil.batchfetchVoucherMark(voucherList);
if (CollectionUtil.isEmpty(voucherMarkList)) {
    return StringUtil.EMPTY_STRING;
}
BatchRecReasonRequest request = new BatchRecReasonRequest();
request.setBizItemIds(voucherMarkList);
Map<String, List<RecReasonDetailDTO>> recReasonDetailDTOMap = relationRecReasonFacadeClient.batchGetRecReason(request);
if (CollectionUtil.isEmpty(recReasonDetailDTOMap)) {
    return StringUtil.EMPTY_STRING;
}
// Parse recommendation texts, prioritize friend recommendations
for (String voucherMark : recReasonDetailDTOMap.keySet()) {
    List<RecReasonDetailDTO> reasonDetailDTOS = recReasonDetailDTOMap.get(voucherMark);
    for (RecReasonDetailDTO recReasonDetailDTO : reasonDetailDTOS) {
        if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.FRIEND, recTypeList, friendRecMaxCount)) {
            friendRecText = recReasonDetailDTO.getRecommendText();
            friendRecMaxCount = recReasonDetailDTO.getCount();
            friendRecMaxCountDetailDTOS = reasonDetailDTOS;
            continue;
        }
        if (needUpdateRecMaxCount(recReasonDetailDTO, RecReasonTypeEnum.LBS, recTypeList, lbsRecMaxCount)) {
            lbsRecText = recReasonDetailDTO.getRecommendText();
            lbsRecMaxCount = recReasonDetailDTO.getCount();
        }
    }
}
return bulidRecText(friendRecMaxCountDetailDTOS, friendRecText, lbsRecText);

3.2.2 Simplify Complex Conditions

Extracting intricate boolean expressions into well‑named helper methods makes the main flow easier to read.

private boolean needUpdateRecMaxCount(RecReasonDetailDTO dto, RecReasonTypeEnum type, List<String> typeList, long currentMax) {
    if (StringUtil.equals(dto.getRecReasonType(), type.name()) &&
        typeList.contains(type.name()) &&
        StringUtil.isNotBlank(dto.getRecommendText()) &&
        dto.getCount() != 0 &&
        Long.valueOf(dto.getCount()) > currentMax) {
        return true;
    }
    return false;
}

3.2.3 Flatten Nested If‑Statements

Early returns for guard conditions eliminate deep nesting and clarify the happy path.

if (Objects.isNull(cardSaveNotifyDTO)) {
    LoggerUtil.warn(LOGGER, "[CardSaveMessage] cardSaveNotifyDTO is null");
    return;
}
LoggerUtil.info(LOGGER, "[CardSaveMessage] receive card save message, cardSaveNotifyDTO=" + cardSaveNotifyDTO);
if (noNeedSendOpenCardMsg(cardSaveNotifyDTO)) {
    LoggerUtil.info(LOGGER, "[CardSaveMessage] not need send open card message, cardSaveNotifyDTO=" + cardSaveNotifyDTO);
    return;
}
CardDO cardDO = CardDAO.queryCardInfoById(cardSaveNotifyDTO.getCardId(), cardSaveNotifyDTO.getUserId());
if (Objects.isNull(cardDO)) {
    LoggerUtil.warn(LOGGER, "[CardSaveMessage] cardDO is null");
    return;
}
openCardServiceManager.sendOpenCardMessage(cardDO);
LoggerUtil.info(LOGGER, "[CardSaveMessage] send open card message, cardSaveNotifyDTO=" + cardSaveNotifyDTO);

3.2.4 Semanticizing Fixed Rules

Replace hard‑coded string concatenations with enumerations that capture the business meaning.

enum CardPointUpdateScene {
    CARD_POINT_UPDATE,
    CARD_POINT_UPDATE_MERCH,
    CARD_POINT_UPDATE_WITH_MEMBER_CENTER,
    CARD_POINT_UPDATE_MERCH_WITH_MEMBER_CENTER
}

if (isMrchCardRemind(appId, appUrl)) {
    args.put(MessageConstant.MSG_REMIND_APP_ID, appId);
    args.put(MessageConstant.MSG_REMEND_APP_URL, appUrl);
    if (StringUtil.isNotBlank(memberCenterUrl)) {
        args.put(MessageConstant.MEMBER_CENTER_URL, memberCenterUrl);
        return remindSceneEnum.getMerchRemindWithMemberScene();
    }
    return remindSceneEnum.getMerchRemindScene();
}

4. Reflection and Summary

Code cleanliness correlates directly with code quality. Refactoring is not an end in itself; its purpose is to make code more maintainable, readable, and efficient. Even small, low‑cost improvements that keep the codebase tidy are worthwhile, especially for engineers with limited experience.

Key take‑aways include removing duplicate code, using clear and expressive naming, adhering to the single‑responsibility principle, and avoiding overly long methods.

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.

JavaSoftware Engineeringcode qualityrefactoringclean code
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.