package LLD.vendingmachine;
import java.util.HashMap;
import java.util.Map;
public class VendingMachineSystem {
class Product {
String code;
String name;
double price;
int quantity;
Product(String code, String name, double price, int quantity) {
this.code = code;
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
interface VendingState {
void select(VendingMachine machine, String code);
void insert(VendingMachine machine, double amount);
void dispense(VendingMachine machine);
void cancel(VendingMachine machine);
}
class IdleState implements VendingState {
@Override
public void select(VendingMachine machine, String code) {
Product product = machine.products.get(code);
if (product == null || product.quantity == 0) {
throw new IllegalStateException("Product unavailable");
}
machine.selected = product;
machine.state = new SelectedState();
}
@Override
public void insert(VendingMachine machine, double amount) {
throw new IllegalStateException("Select Product first");
}
@Override
public void dispense(VendingMachine machine) {
throw new IllegalStateException("Select Product first");
}
@Override
public void cancel(VendingMachine machine) {
throw new IllegalStateException("No transaction");
}
}
class SelectedState implements VendingState {
@Override
public void select(VendingMachine machine, String code) {
throw new IllegalStateException("Product already selected");
}
@Override
public void insert(VendingMachine machine, double amount) {
machine.money += amount;
if (machine.money >= machine.selected.price) {
machine.state = new DispensingState();
}
}
@Override
public void dispense(VendingMachine machine) {
throw new IllegalStateException("Insufficient money");
}
@Override
public void cancel(VendingMachine machine) {
System.out.println("Transaction cancelled. Returning: $" + machine.money);
machine.reset();
}
}
class DispensingState implements VendingState {
@Override
public void select(VendingMachine machine, String code) {
throw new IllegalStateException("Transaction in progress");
}
@Override
public void insert(VendingMachine machine, double amount) {
throw new IllegalStateException("Payment complete");
}
@Override
public void dispense(VendingMachine machine) {
machine.selected.quantity--;
double change = machine.money - machine.selected.price;
System.out.println("Dispensing " + machine.selected.name);
System.out.println("Change: $" + change);
machine.reset();
}
@Override
public void cancel(VendingMachine machine) {
System.out.println("Too late to cancel, dispensing in progress.");
machine.reset();
}
}
class VendingMachine {
Map<String, Product> products = new HashMap<>();
VendingState state = new IdleState();
Product selected;
double money;
void select(String code) {
state.select(this, code);
}
void insert(double amount) {
state.insert(this, amount);
}
void dispense() {
state.dispense(this);
}
void cancel() {
state.cancel(this);
}
void reset() {
selected = null;
money = 0;
state = new IdleState();
}
}
public static void main(String[] args) {
// 1. Initialize the system
VendingMachineSystem system = new VendingMachineSystem();
VendingMachine machine = system.new VendingMachine();
// 2. Load products into the machine
machine.products.put("A1", system.new Product("A1", "Coke", 1.50, 5));
machine.products.put("B2", system.new Product("B2", "Chips", 2.00, 3));
machine.products.put("C3", system.new Product("C3", "Water", 1.00, 0)); // Out of stock
System.out.println("Vending Machine Setup Complete.\n");
try {
// Test Case 1: Successful Purchase with Exact Change
System.out.println("--- Test 1: Buying Chips ---");
machine.select("B2");
System.out.println("Selected Chips. Price: $2.00");
machine.insert(2.00);
machine.dispense();
// Test Case 2: Successful Purchase with Overpayment
System.out.println("\n--- Test 2: Buying Coke (with extra money) ---");
machine.select("A1");
System.out.println("Selected Coke. Price: $1.50");
machine.insert(1.00);
machine.insert(1.00); // Total $2.00, triggers DispensingState
machine.dispense(); // Should return $0.50 change
// Test Case 3: Cancelling a transaction
System.out.println("\n--- Test 3: Cancelling Transaction ---");
machine.select("A1");
System.out.println("Selected Coke. Price: $1.50");
machine.insert(1.00);
machine.cancel();
// Test Case 4: Trying to buy out of stock item
System.out.println("\n--- Test 4: Buying Out of Stock Item ---");
machine.select("C3"); // Should throw an exception
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Top comments (0)