Refactor an OrderProcessor that validates and prices orders, manages product stock, and records confirmation messages.
The starter returns the required results, but it is a God class: inventory rules, order workflow, pricing, and notification history all live in one place. Preserve the public API while giving the independent responsibilities focused owners.
OrderProcessor() creates a processor with these products:"LAPTOP": 10 units at $1000.00 each;"PHONE": 25 units at $500.00 each;"TABLET": 15 units at $300.00 each.String placeOrder(String productId, int quantity, String customerEmail):"INVALID_ORDER" when productId is empty, quantity is not positive, or the email does not contain @ with at least one character on each side;"OUT_OF_STOCK" when the product is unknown or fewer than quantity units remain;"ORD-1", "ORD-2", and so on.int stockOf(String productId) returns its current stock, or 0 for an unknown product.int orderCount() returns the number of successful orders.String[] confirmations() returns the recorded messages in order as "EMAIL <email> | <orderId> confirmed | total $<amount>", with the amount to two decimal places.Rejected orders must not change stock, consume an order ID, or record a confirmation.
The refactored design should contain these focused collaborators:
OrderProcessor owns validation, product pricing, total calculation, ID generation, and workflow coordination.InventoryManager owns stock checks and stock updates.NotificationService owns confirmation formatting and history.OrderProcessor must be constructible with an InventoryManager and a NotificationService, so callers can supply those dependencies. Also keep the no-argument constructor required by the judge; it may assemble default collaborators.
Input:
Output:
Explanation: The processor calculates $2000.00, the inventory manager removes two laptops, and the notification service stores the confirmation.
Input:
Output:
Explanation: The failed phone order has no side effects, so the successful tablet order receives the first order ID.
0 <= productId.length <= 20-100 <= quantity <= 1000 <= customerEmail.length <= 50100 calls are made across all methods.The implementation below is behaviorally correct, but one class owns stock, order policy, workflow, and confirmation output. Refactor it without changing any public result.
Full marks when order validation, pricing and workflow live in OrderProcessor, stock state and mutations live in InventoryManager, and confirmation wording and history live in NotificationService. Equivalent focused decompositions are acceptable; lose points when one class still owns all three concerns.
Full marks when OrderProcessor can receive its inventory and notification collaborators through construction and uses those same instances for every order. A no-argument convenience constructor may create defaults for the judge. Lose points when placeOrder constructs fresh collaborators or reaches into their internal collections.
Full marks when invalid or unavailable orders change nothing, successful orders reduce stock once, reserve consecutive IDs only for successes, calculate the correct product total and record exactly one confirmation. Lose points for printing, exposing mutable collections, or allowing stock checks and updates to disagree.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new OrderProcessor() | null |
| placeOrder("LAPTOP", 2, "alice@example.com") | "ORD-1" |
| stockOf("LAPTOP") | 8 |
| orderCount() | 1 |
| confirmations() | ["EMAIL alice@example.com | ORD-1 confirmed | total $2000.00"] |
The processor validates and prices the order, the inventory manager removes two laptops, and the notification service records the finished confirmation.
Run checks these cases. Submit also runs a larger hidden set.

