ChatGPT:
Question:
You are designing a system that processes customer orders. Each order has a status that can change over time. The possible statuses are:
NEW
(Order just created)PROCESSING
(Currently being processed)SHIPPED
(Sent to the customer)DELIVERED
(Received by the customer)CANCELLED
(Order was cancelled)
Each status has the following behavior:
- Some statuses can transition only to specific other statuses.
- Each status should have a method
canTransitionTo(OrderStatus nextStatus)
that validates if the transition is allowed. - Each status should have a
getDisplayName()
method to return a user-friendly name.
Question Tasks:
- Implement the
OrderStatus
in the most efficient way. - Ensure that invalid transitions are prevented.
- Provide a simple test case to demonstrate how an order changes status correctly.
This question naturally leads to using an enum
because:
- Enums provide a fixed set of constants, perfect for representing statuses.
- Enums can have methods and fields, making them ideal for defining transition rules.
- Enums improve code readability and maintainability compared to using plain integers or strings.
Would you like a sample implementation for this? π
prompt: yes
ChatGPT:
Hereβs an implementation using an enum
to handle order statuses efficiently:
public enum OrderStatus {
NEW("New Order") {
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == PROCESSING || nextStatus == CANCELLED;
}
},
PROCESSING("Processing Order") {
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == SHIPPED || nextStatus == CANCELLED;
}
},
SHIPPED("Shipped Order") {
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == DELIVERED;
}
},
DELIVERED("Delivered Order") {
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return false; // Final status, cannot transition further
}
},
CANCELLED("Cancelled Order") {
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return false; // Cannot transition from a cancelled order
}
};
private final String displayName;
OrderStatus(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
// Abstract method to enforce transition logic in each enum constant
public abstract boolean canTransitionTo(OrderStatus nextStatus);
}
public class Order {
private OrderStatus status;
public Order() {
this.status = OrderStatus.NEW;
}
public boolean changeStatus(OrderStatus newStatus) {
if (status.canTransitionTo(newStatus)) {
this.status = newStatus;
System.out.println("Order status changed to: " + status.getDisplayName());
return true;
} else {
System.out.println("Invalid transition from " + status + " to " + newStatus);
return false;
}
}
public OrderStatus getStatus() {
return status;
}
}
public class OrderStatusTest {
public static void main(String[] args) {
Order order = new Order();
System.out.println("Initial Status: " + order.getStatus());
order.changeStatus(OrderStatus.PROCESSING); // Valid transition
order.changeStatus(OrderStatus.SHIPPED); // Valid transition
order.changeStatus(OrderStatus.DELIVERED); // Valid transition
order.changeStatus(OrderStatus.CANCELLED); // Invalid transition (should fail)
}
}
Initial Status: NEW
Order status changed to: Processing Order
Order status changed to: Shipped Order
Order status changed to: Delivered Order
Invalid transition from DELIVERED to CANCELLED
β
Ensures type safety β No invalid values can be assigned.
β
Encapsulates logic β Each status defines its own transition rules.
β
Readability & Maintainability β Clear, structured, and easy to modify.
β
Performance β Enums are more efficient than using a Map
or multiple if-else
statements.
Would you like to extend this with additional features, like tracking the history of status changes? π