Introduction to Finite State Machines and Their Application in Business Systems
This article introduces deterministic finite state machines, explains their core elements, discusses their advantages for code clarity and separation of concerns, and demonstrates a practical Java implementation for order processing in a commerce platform, including configuration, business logic, exception handling, and extensibility considerations.
State Machine Introduction
The deterministic finite state machine (FSM), also known as a finite automaton, is widely used in software such as compilers, regular expression engines, and game development. An FSM maintains a set of states and events, reacts to specific event inputs by transitioning between states, and executes associated actions.
State Machine Elements
State set (states)
Event set (events)
Guards (detectors)
Transitions (converters)
Context
Business System Usage Scope
In internet‑based business systems, any scenario involving documents with complex state flows can benefit from a state machine.
Business System Application
By configuring a state transition diagram and encapsulating the corresponding business logic, the system can react to a specific event (e.g., an API request) by moving to a new state and executing the related logic.
Advantages of State Machines
Good code is intuitive and easy to understand; it follows a clear logical flow that aligns with how most people think. Complex problems can be broken down into many simple ones, and state machines embody this “divide‑and‑conquer” mindset, enabling layered architectures that separate business logic, control logic, and data.
Applying a state machine in a business system not only introduces a dedicated component but also defines a “state‑machine architecture” that cleanly splits code logic and connects modules through a well‑defined mechanism, preserving design principles over long‑term iterations.
Beyond separating business logic, it also isolates control logic. As Robert Kowalski argued, algorithm = logic + control; separating them improves maintainability. The state machine takes over much of the control work, letting developers focus on business logic.
Visually, the code eliminates scattered if…else… statements, reducing cognitive noise.
// Frequent state checks
if (state == EOrderState.WAIT_PAY) {
...
} else if (state == EOrderState.PAYED) {
...
}
// Execute business logic
...In summary, introducing a state machine lowers learning and maintenance costs.
State Machine Practice in ZheZhe YanXuan Transactions
Understanding the Business
First, draw a state‑transition diagram. Identify each document state and the actions (events) that cause transitions, e.g., an order moves from “WAIT_PAY” to “PAYED” after a payment event.
Configure the State Machine
Translate the diagram into code that resembles natural language.
StateMachineConf conf = new StateMachineConf();
conf.source(EOrderState.WAIT_PAY)
.onEvent(EOrderEvent.PAY)
.target(EOrderState.PAYED)
.transition(userPayTransition)
...Define all states and events as enums.
/**
* State definitions
*/
public enum EOrderState implements IFSMState {
WAIT_PAY(1, "待支付"),
PAYED(2, "已支付"),
...
} /**
* Event definitions
*/
public enum EOrderEvent implements IFSMEvent {
PAY(1, "用户支付"),
APPLY_FOR_REFUND(2, "申请退款"),
...
}Full configuration example:
StateMachineConf conf = new StateMachineConf();
conf.source(s1).onEvent(e1).target(s2).transition(t1)
.and().source(s2).onEvent(e2).target(s3).transition(t2)
...
fsm.setName("转转严选订单状态机");
fsm.config(conf);Business Logic
The transition implementation contains the actual business actions.
/**
* Business logic implementation
*/
public class BuyerPayTransition implements IFSMTransition
{
@Override
public boolean onGuard(OrderFSMContext context, IFSMState targetState) {
// guard logic, validation
}
@Override
public void onTransition(OrderFSMContext context, IFSMState targetState) {
// transition logic, business processing
}
}Trigger the state machine from a service layer:
@Service
public class OrderService {
@Resource
private StateMachine fsm;
public void userPay(Order order) {
OrderFSMContext context = new OrderFSMContext();
context.setSourceState(order.getState());
context.setEvent(EOrderEvent.PAY);
context.setOrder(order);
fsm.fire(context);
}
}Exception Cases
When duplicate events occur, use optimistic locking to prevent concurrent state changes.
update order set state=3 where id=xxx and state=2;If no transition matches the current state and event, configure a callback to handle the situation.
StateMachineConf conf = new StateMachineConf();
conf.source(s1).onEvent(e1).target(s2).transition(t1)
.and().source(s2).onEvent(e2).target(s3).transition(t2)
...
fsm.setName("转转严选订单状态机");
fsm.config(conf);
fsm.setTransBlock(orderTransBlock); // callback for blocked transitions @Component
@Slf4j
public class OrderFSMTransBlock implements IFSMTransBlock
{
@Override
public boolean onTransBlock(OrderFSMContext context) {
log.info("状态机无法跳转...");
return false;
}
}Extensibility Considerations
Example: when a user buys a phone case together with a phone, both must be refunded together.
public class ApplyForRefundTransition implements IFSMTransition
{
@Override
public void onTransition(OrderFSMContext context, IFSMState targetState) {
// handle phone refund
...
// handle phone case refund
...
}
}To avoid coupling, use an annotation‑driven approach:
@Transition(source = EOrderState.PAYED, event = EOrderEvent.APPLY_FOR_REFUND, fsm = "转转严选订单状态机")
public void phoneShellRefund(OrderFSMContext context) {
// handle phone case refund logic
}Conclusion
State machines are not a sophisticated technology; they provide a different perspective for system design, helping to create clearer, more maintainable architectures.
Author: Gao Hongjie, R&D Engineer at ZheZhe C2B Business.
Zhuanzhuan Tech
A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.
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.