Eliminate Java Code Duplication with Design Patterns and Annotations
This article demonstrates how to reduce repetitive Java code in business applications by applying the Template Method and Factory design patterns, leveraging Spring’s IoC for dynamic cart selection, using custom annotations with reflection to serialize API parameters, and employing bean‑mapping utilities to automate DTO‑DO conversions, thereby improving maintainability and scalability.
1. Use Factory + Template Method to remove if…else and duplicate code
We illustrate a shopping‑cart example with three user types (Normal, VIP, Internal). The original implementation repeats 70% of the logic across three separate classes. By extracting the common workflow into an abstract class AbstractCart and defining abstract methods for the variable parts ( processCouponPrice and processDeliveryPrice), each concrete cart only implements its specific rules. The controller can then obtain the appropriate bean via Spring’s IoC using the user category as part of the bean name, eliminating the cascade of if statements.
public abstract class AbstractCart {
public Cart process(long userId, Map<Long, Integer> items) {
// common logic
}
protected abstract void processCouponPrice(long userId, Item item);
protected abstract void processDeliveryPrice(long userId, Item item);
}2. Use Annotations + Reflection to eliminate repetitive parameter handling
For bank APIs that require fixed‑length, specially padded strings, we define a class‑level annotation @BankAPI (url, description) and a field‑level annotation @BankAPIField (order, length, type). A generic remoteCall method reads these annotations via reflection, formats each field according to its type (string left‑padded with ‘_’, numeric left‑padded with ‘0’, monetary padded after scaling), appends an MD5 signature, and sends the request. Individual service methods simply populate POJOs and invoke remoteCall, removing all duplicated formatting and signing code.
private static String remoteCall(AbstractAPI api) throws IOException {
BankAPI bankAPI = api.getClass().getAnnotation(BankAPI.class);
StringBuilder sb = new StringBuilder();
Arrays.stream(api.getClass().getDeclaredFields())
.filter(f -> f.isAnnotationPresent(BankAPIField.class))
.sorted(Comparator.comparingInt(f -> f.getAnnotation(BankAPIField.class).order()))
.peek(f -> f.setAccessible(true))
.forEach(f -> {
BankAPIField meta = f.getAnnotation(BankAPIField.class);
Object value = /* reflect get value */;
// format based on meta.type()
});
sb.append(DigestUtils.md2Hex(sb.toString()));
// send HTTP request
}3. Use Property‑Copy Tools to avoid manual DTO‑DO mapping
Manual copying between layers (DTO, DO, VO) is error‑prone, especially with many fields. Instead of writing dozens of setter calls, a utility such as BeanUtils.copyProperties(source, target, "ignoreField") copies matching properties automatically, allowing selective exclusion and reducing bugs caused by swapped or duplicated assignments.
ComplicatedOrderDTO dto = new ComplicatedOrderDTO();
ComplicatedOrderDO do = new ComplicatedOrderDO();
BeanUtils.copyProperties(dto, do, "id");In summary, the three common sources of code duplication—parallel classes with similar logic, hard‑coded data‑formatting routines, and repetitive bean mapping—can be mitigated respectively by extracting shared behavior into abstract classes (Template Method), by describing rules with annotations and processing them via reflection, and by leveraging existing mapping libraries.
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
