Port Round 2 to Java (OrderBook): 14 tests total green, START state preserved
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package orderbookdomain;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class Order {
|
||||
|
||||
private final int id;
|
||||
private final String customer;
|
||||
|
||||
private OrderStatus status;
|
||||
private Instant finalizedAt;
|
||||
|
||||
Order(int id, String customer) {
|
||||
this.id = id;
|
||||
this.customer = customer;
|
||||
this.status = OrderStatus.PENDING;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public OrderStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Instant getFinalizedAt() {
|
||||
return finalizedAt;
|
||||
}
|
||||
|
||||
void setStatus(OrderStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
void setFinalizedAt(Instant finalizedAt) {
|
||||
this.finalizedAt = finalizedAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package orderbookdomain;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OrderBook {
|
||||
|
||||
private final Duration paymentWindow;
|
||||
private final Map<Integer, Order> ordersById = new HashMap<>();
|
||||
private int nextId = 1;
|
||||
|
||||
public OrderBook() {
|
||||
this(Duration.ofDays(14));
|
||||
}
|
||||
|
||||
public OrderBook(Duration paymentWindow) {
|
||||
this.paymentWindow = paymentWindow;
|
||||
}
|
||||
|
||||
public List<Order> getOrders() {
|
||||
return List.copyOf(ordersById.values());
|
||||
}
|
||||
|
||||
public Order openOrder(String customer) {
|
||||
Order order = new Order(nextId++, customer);
|
||||
ordersById.put(order.getId(), order);
|
||||
return order;
|
||||
}
|
||||
|
||||
public Order getOrder(int orderId) {
|
||||
Order order = ordersById.get(orderId);
|
||||
if (order == null) {
|
||||
throw new IllegalStateException("Unknown order id " + orderId + ".");
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
public void finalizeOrder(int orderId, Instant finalizedAt) {
|
||||
Order order = getOrder(orderId);
|
||||
requireStatus(order, OrderStatus.PENDING, "finalize");
|
||||
order.setStatus(OrderStatus.WAITING_FOR_PAYMENT);
|
||||
order.setFinalizedAt(finalizedAt);
|
||||
}
|
||||
|
||||
public void payOrder(int orderId, Instant paidAt) {
|
||||
Order order = getOrder(orderId);
|
||||
requireStatus(order, OrderStatus.WAITING_FOR_PAYMENT, "pay");
|
||||
if (Duration.between(order.getFinalizedAt(), paidAt).compareTo(paymentWindow) > 0) {
|
||||
order.setStatus(OrderStatus.CANCELLED);
|
||||
throw new IllegalStateException(
|
||||
"Payment for order " + orderId + " arrived after the payment window; the order was cancelled.");
|
||||
}
|
||||
order.setStatus(OrderStatus.FULFILLING);
|
||||
}
|
||||
|
||||
public void shipOrder(int orderId) {
|
||||
Order order = getOrder(orderId);
|
||||
requireStatus(order, OrderStatus.FULFILLING, "ship");
|
||||
order.setStatus(OrderStatus.DELIVERED);
|
||||
}
|
||||
|
||||
public void cancelOrder(int orderId) {
|
||||
Order order = getOrder(orderId);
|
||||
if (order.getStatus() != OrderStatus.PENDING && order.getStatus() != OrderStatus.WAITING_FOR_PAYMENT) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot cancel order " + orderId + " in status " + order.getStatus() + ".");
|
||||
}
|
||||
order.setStatus(OrderStatus.CANCELLED);
|
||||
}
|
||||
|
||||
private static void requireStatus(Order order, OrderStatus expected, String action) {
|
||||
if (order.getStatus() != expected) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot " + action + " order " + order.getId() + " in status " + order.getStatus()
|
||||
+ " (expected " + expected + ").");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package orderbookdomain;
|
||||
|
||||
public enum OrderStatus {
|
||||
PENDING,
|
||||
WAITING_FOR_PAYMENT,
|
||||
FULFILLING,
|
||||
DELIVERED,
|
||||
CANCELLED
|
||||
}
|
||||
Reference in New Issue
Block a user