Fundamentals 13 min read

A Java-Based Scenario Execution Framework Using Design Patterns

The article presents a Java‑based scenario execution framework that leverages design patterns, annotations, enums and a generic factory to replace repetitive if/else branches with abstract scene interfaces and concrete implementations, enabling developers to add new business cases by simply creating a class and enum constant while the infrastructure automatically discovers and wires it, improving extensibility, readability and code quality.

DaTaobao Tech
DaTaobao Tech
DaTaobao Tech
A Java-Based Scenario Execution Framework Using Design Patterns

In software development, handling diverse business scenarios often requires a flexible and extensible architecture. This article, based on Java, demonstrates how to use design patterns and tooling to reduce code redundancy, improve development efficiency, and enhance code quality.

Typical use‑case: processing different logic according to a user’s eligibility for a red‑packet, contract status, etc. Instead of writing repetitive if/else branches, the solution introduces an abstract scene interface, concrete scene implementations, a scene annotation, an enum‑based scene identifier, and a generic factory that resolves the correct implementation at runtime.

Key advantages :

Developers only need to implement the concrete scene class; the surrounding interface, factory and annotation handling are provided automatically.

The design preserves extensibility and readability when new scenarios are added.

Below are the essential code artifacts used in the framework.

public interface SceneHandleBase { /** * Execute the business logic */ G doCallback(T params); }

@Slf4j public abstract class AbstractSceneHandleBase implements SceneHandleBase { /** * Concrete scene execution method */ public abstract G execute(T params); /** * Wrap execution with error logging and monitoring */ @Override public G doCallback(T params) { try { return execute(params); } catch (Exception e) { log.error("{}, |StatusHandleBase_doCallback|error|,className:{}, doCallback, params:{}, msg:{}", EagleEye.getTraceId(), this.getClass().getSimpleName(), JSON.toJSONString(params), e.getMessage(), e); throw e; } } }

@Component @Slf4j public class ContractStartedSceneHandleImpl extends AbstractSceneHandleBase > { @Resource private PurchasePayLaterBizService purchasePayLaterBizService; @Override public boolean judge(User params) { return true; } @Override public TResult execute(ContractEvent contractEvent) { UserSignResult userSignResult = purchasePayLaterBizService.buildUserSignResult(contractEvent, SignStatus.SIGN_SUCCESS); return purchasePayLaterBizService.updateSignStatus(userSignResult); } }

@Component @Slf4j public class ContractClosedSceneHandleImpl extends AbstractSceneHandleBase > { @Resource private PurchasePayLaterBizService purchasePayLaterBizService; @Override public boolean judge(User params) { return true; } @Override public TResult execute(ContractEvent contractEvent) { UserSignResult userSignResult = purchasePayLaterBizService.buildUserSignResult(contractEvent, SignStatus.SIGN_FAIL); return purchasePayLaterBizService.updateSignStatus(userSignResult); } }

/** * Annotation to bind a scene implementation to a fully‑qualified enum value */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface SceneHandleType { String value(); }

public interface SceneEnumBase { /** * Return the enum constant name */ String getSceneName(); }

public enum ContractStatusEnum implements SceneEnumBase { STARTED, FROZEN, CLOSED, NO_ENTRY; @Override public String getSceneName() { return this.name(); } }

public class SceneHandleFactory implements ApplicationContextAware, InitializingBean { private final Map > statusMap = new HashMap<>(); private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() throws Exception { Map beans = applicationContext.getBeansOfType(SceneHandleBase.class); if (MapUtils.isEmpty(beans)) return; for (SceneHandleBase handler : beans.values()) { SceneHandleType type = handler.getClass().getAnnotation(SceneHandleType.class); if (type == null) continue; String key = type.value(); statusMap.computeIfAbsent(key, k -> new ArrayList<>()).add(handler); } } public SceneHandleBase getSceneHandle(SceneEnumBase status, A params) { String key = String.join(".", status.getClass().getName(), status.getSceneName()); List candidates = statusMap.get(key); if (candidates != null) { for (SceneHandleBase h : candidates) { if (h.judgeConditions(params)) { return h; } } } return null; } }

Usage example:

SceneHandleBase > handle = sceneHandleFactory.getSceneHandle(ContractStatusEnum.valueOf(event.getStatus()), null); TResult result = handle.doCallback(event);

The framework abstracts away the boilerplate of condition checks, factory registration, and annotation processing. Adding a new business scenario only requires defining a new enum constant (if needed) and implementing a concrete scene class annotated with @SceneHandleType . The rest of the infrastructure automatically discovers and wires the implementation, resulting in clean, maintainable, and highly extensible code.

In summary, the article walks through a practical case study that evolves from raw conditional logic to a fully abstracted, annotation‑driven scenario execution tool, illustrating the power of design patterns, high cohesion, low coupling, and generic factories in modern Java backend development.

design patternsjavasoftware architectureFactory PatternScenario Handling
DaTaobao Tech
Written by

DaTaobao Tech

Official account of DaTaobao Technology

0 followers
Reader feedback

How this landed with the community

login 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.