How to Eliminate Duplicate Code with Factory & Template Method Patterns in Java

This article explains why duplicate code harms maintainability, then demonstrates step‑by‑step refactoring techniques—using factory and template method patterns, custom annotations with reflection, and BeanUtils—to consolidate business logic for different cart types and API calls while preserving extensibility.

JavaEdge
JavaEdge
JavaEdge
How to Eliminate Duplicate Code with Factory & Template Method Patterns in Java

Why Duplicate Code Is Dangerous

Many CRUD engineers feel their work lacks technical depth because they rarely use design patterns or high‑concurrency techniques, leading to repetitive code that is hard to maintain. Duplicate code can cause bugs when a change is missed in one place, introduce subtle errors when similar code is edited inconsistently, and increase the risk of incorrect logic across many methods.

Factory + Template Method Refactoring

To handle three different cart behaviours (normal user, VIP user, internal user) without duplicating initialization, total price, shipping, and discount calculations, the article extracts the common workflow into an abstract class AbstractCart and defines two abstract methods for the variable parts: processCouponPrice – calculates product discounts. processDeliveryPrice – calculates shipping fees.

The three concrete carts extend AbstractCart and implement only the specific logic:

NormalUserCart – 0 discount, 10% shipping.

VipUserCart – inherits normal logic and overrides the multi‑buy discount.

InternalUserCart – free shipping and no discount.

Annotation + Reflection Refactoring

The article then tackles a banking API that requires fixed‑length, left‑padded strings for text fields, right‑padded zeros for numbers, and special handling for monetary values. Instead of hard‑coding each parameter, it defines POJO classes ( CreateUserAPI, PayAPI) annotated with a custom @BankAPI (URL and description) and @BankAPIField (order, type, length).

public class CreateUserAPI {
    private String name;
    private String identity;
    private String mobile;
    private int age;
}

A generic remoteCall(AbstractAPI api) method uses reflection to:

Read the @BankAPI annotation for the endpoint URL.

Collect all fields annotated with @BankAPIField, sort them by order, and make them accessible.

For each field, retrieve its value, format it according to its type (S‑string, N‑number, M‑money), pad appropriately, and append to a StringBuilder.

Append an MD5 signature and send the request via HTTP.

Property Copy Issues

When converting between DTO, DO, and VO objects in a three‑layer architecture, manual field‑by‑field assignment quickly becomes error‑prone, especially with dozens or hundreds of properties. The article shows a typical buggy snippet where fields are mismatched or copied from the wrong object.

ComplicatedOrderDTO orderDTO = new ComplicatedOrderDTO();
ComplicatedOrderDO orderDO = new ComplicatedOrderDO();
orderDO.setCommentable(orderDTO.isComplainable()); // swapped
orderDO.setDeliveryManMobile(orderDO.getDeliveryManMobile()); // self‑reference

Using a mapping utility such as BeanUtils.copyProperties with an ignore list can automate this process and reduce mistakes.

Conclusion

Duplicate code inevitably leads to bugs. The recommended strategies are:

Extract common logic into a superclass and use the Template Method pattern for variations.

Replace hard‑coded rule implementations with custom annotations and reflection to separate rule data from processing code.

Leverage bean‑mapping tools for DTO/DO conversions and add unit tests to verify field mappings.

By applying these techniques, projects can achieve better maintainability, extensibility, and adherence to the Open/Closed principle.

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.

Design PatternsJavaReflectionannotationsFactory PatternTemplate Method
JavaEdge
Written by

JavaEdge

First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.

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.