Common Code Smells and Optimization Practices in Backend Development
This article examines typical code quality issues such as meaningless naming, overly long methods, inefficient batch operations, improper dependency handling, excessive parameters, duplicated logic, and offers concrete refactoring examples and best‑practice guidelines to improve maintainability and performance of backend Java code.
The article starts by pointing out that developers often encounter both elegant and bizarre code, emphasizing that code is a programmer's business card and should strive for high quality rather than merely functional correctness.
Naming Without Business Semantics
Example code shows a method
public void handleTask(Long taskId, Intger status) { TaskModel taskModel = taskDomainService.getTaskById(taskId); Assert.notNull(taskModel); taskModel.setStatus(status); taskDomainService.preserveTask(taskModel); }. Although the implementation is straightforward, the method name handleTask is too generic and does not convey the actual business intent of changing a task's status.
Overly Long Methods
A sample method
public void shelveFreshGoods() { //检查货品 //几十行代码(检查重量、检查新鲜度等等) //货品摆渡 //几十行代码(生成货品编号、装载等等) //上架 //几十行代码(货品打标、绑定库存等等) ... }mixes several business steps, making maintenance difficult. The refactored version splits the logic into three clear methods:
public void shelveFreshGoods() { check(); transfer(); shelve(); }.
Inefficient Batch Insertion
Loop‑based insertion for(TaskPO taskPO : taskPOList) { saveTask(taskPO); } causes many round‑trips to the database. The article recommends using a single batch insert in the mapper:
<insert id="batchSaveTask" parameterType="java.util.List"> insert into task (c_id,c_name,c_type,c_content,c_operator,i_container_type,c_warehouse_type) values <foreach collection="taskList" item="item" open="(" close=")" separator=","> (#{item.id},#{item.type},#{item.content},#{item.operator},#{item.containerType},#{item.warehouseType}) </foreach> </insert>, which reduces database interactions to one.
Upsert Instead of Separate Select‑Then‑Update
Typical code first queries a task and then inserts or updates it:
Task task = taskBizService.queryTaskByName(); if(Objects.isNull(task)) { taskBizService.saveTask(); } taskBizService.updateTask();. The article suggests using a single upsert statement such as
insert into task(...) values (...) on conflict(c_name) do update set c_content=#{content}to avoid multiple round‑trips.
Violating Dependency Inversion
Hard‑coding a DingTalk notification method public boolean sendDingTalk(Message message) { ... } ties business logic to a concrete implementation. Refactoring introduces an abstraction:
public interface NotifyMessage { boolean notifyMessage(Message message); } public class DingTalk implements NotifyMessage { @Override public boolean notifyMessage(Message message) { ... } } public class WeChat implements NotifyMessage { @Override public boolean notifyMessage(Message message) { ... } }, allowing the notification channel to change without modifying business code.
Long SQL Statements
Very long SQL queries with many joins and sub‑queries are hard to read and maintain. The article advises using wide tables, views, or stored procedures to simplify queries.
Excessive Method Parameters
Methods with many primitive parameters, e.g.,
Integer preserveTask(String taskId, String taskName, String taskType, String taskContent, String operator, Integer containerType, String warehouseType), should be replaced with a parameter object like Integer preserveTask(TaskDO taskDO) to improve extensibility and comply with the Open‑Closed Principle.
Duplicate Code
Repeated logic can be extracted into utility methods, such as collection emptiness checks: original if(null != taskList && !taskList.isEmpty()) { ... } becomes if(CollectionUtils.isNotEmpty(taskList)) { ... }.
Boolean to Integer Conversion
Instead of verbose if‑else, use return BooleanUtils.toInteger(switcher);.
Lambda for Collection Filtering
Replace manual loops with streams:
List<Student> oldStudents = studentList.stream().filter(s -> s.getAge() > 18).collect(Collectors.toList());.
Optional to Reduce Null Checks
Simplify null handling:
public String getTaskName(Task task) { return Optional.ofNullable(task).map(Task::getName).orElse("unDefined"); }.
In summary, the article encourages developers to recognize these "odd" code patterns, refactor them using clean‑code principles, and adopt reusable utilities to produce more maintainable, readable, and efficient backend systems.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
DataFunSummit
Official account of the DataFun community, dedicated to sharing big data and AI industry summit news and speaker talks, with regular downloadable resource packs.
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.
