1⃣ Parking Lot System 🚗
Design Patterns Used:
• Singleton → To ensure a single instance of the parking system
• Factory → To create different types of parking spots (Compact,
Large, Handicapped)
• Strategy → For pricing strategies (Hourly, Flat Rate, Subscription)
• Observer → To notify users when a parking spot is available
• State → To track parking slot availability (Empty, Occupied,
Reserved)
🔗 Popular Question:
• Design a multi-level parking lot with different parking spot types
and a billing system.
+--------------------+
| Vehicle |
|--------------------|
| + numberPlate |
| + vehicleType |
+--------------------+
|
| Inheritance
↓
+-------------------+ +-------------------+
+-------------------+
| Car | | Bike | |
Truck |
+-------------------+ +-------------------+
+-------------------+
+-----------------------+
| ParkingSpot |
|-----------------------|
| + spotId |
| + isAvailable |
| + pricePerHour |
+-----------------------+
|
| Inheritance
↓
+------------------+ +------------------+
+------------------+
| CompactSpot | | LargeSpot | |
HandicappedSpot |
+------------------+ +------------------+
+------------------+
+--------------------+
| ParkingFloor |
|--------------------|
| + floorNumber |
| + spots[] |
+--------------------+
+--------------------+
| ParkingLot |
|--------------------|
| + levels[] |
| + addVehicle() |
| + removeVehicle() |
| + generateTicket()|
+--------------------+
+------------------+
| ParkingTicket |
|------------------|
| + entryTime |
| + exitTime |
| + calculateFee()|
+------------------+
+------------------+
| Payment |
|------------------|
| + payAmount() |
+------------------+
import [Link].*;
// Step 1: Define Vehicle Types
abstract class Vehicle {
protected String numberPlate;
protected VehicleType vehicleType;
public Vehicle(String numberPlate, VehicleType type)
{
[Link] = numberPlate;
[Link] = type;
}
public VehicleType getVehicleType() {
return vehicleType;
}
}
class Car extends Vehicle {
public Car(String numberPlate) {
super(numberPlate, [Link]);
}
}
class Bike extends Vehicle {
public Bike(String numberPlate) {
super(numberPlate, [Link]);
}
}
class Truck extends Vehicle {
public Truck(String numberPlate) {
super(numberPlate, [Link]);
}
}
// Step 2: Enum for Vehicle and Spot Types
enum VehicleType { CAR, BIKE, TRUCK }
enum SpotType { COMPACT, LARGE, HANDICAPPED }
// Step 3: Define Parking Spot
abstract class ParkingSpot {
protected int spotId;
protected boolean isAvailable;
protected double pricePerHour;
protected SpotType spotType;
public ParkingSpot(int spotId, double pricePerHour,
SpotType type) {
[Link] = spotId;
[Link] = true;
[Link] = pricePerHour;
[Link] = type;
}
public boolean isAvailable() {
return isAvailable;
}
public void occupySpot() {
isAvailable = false;
}
public void freeSpot() {
isAvailable = true;
}
public double getPricePerHour() {
return pricePerHour;
}
}
// Different Types of Spots
class CompactSpot extends ParkingSpot {
public CompactSpot(int id) {
super(id, 10.0, [Link]);
}
}
class LargeSpot extends ParkingSpot {
public LargeSpot(int id) {
super(id, 15.0, [Link]);
}
}
class HandicappedSpot extends ParkingSpot {
public HandicappedSpot(int id) {
super(id, 5.0, [Link]);
}
}
// Step 4: Parking Floor
class ParkingFloor {
private int floorNumber;
private List<ParkingSpot> spots;
public ParkingFloor(int number) {
[Link] = number;
[Link] = new ArrayList<>();
}
public void addSpot(ParkingSpot spot) {
[Link](spot);
}
public ParkingSpot findAvailableSpot(VehicleType
vehicleType) {
for (ParkingSpot spot : spots) {
if ([Link]()) {
return spot;
}
}
return null; // No available spot
}
}
// Step 5: Parking Ticket
class ParkingTicket {
private long entryTime;
private long exitTime;
private ParkingSpot spot;
public ParkingTicket(ParkingSpot spot) {
[Link] = [Link]();
[Link] = spot;
}
public void markExit() {
[Link] = [Link]();
}
public double calculateFee() {
long duration = (exitTime - entryTime) / (1000 *
60 * 60); // Convert ms to hours
return [Link]() * [Link](1,
duration);
}
}
// Step 6: Parking Lot
class ParkingLot {
private static ParkingLot instance;
private List<ParkingFloor> floors;
private Map<String, ParkingTicket> activeTickets;
private ParkingLot(int numFloors) {
floors = new ArrayList<>();
activeTickets = new HashMap<>();
for (int i = 0; i < numFloors; i++) {
[Link](new ParkingFloor(i));
}
}
public static ParkingLot getInstance(int numFloors)
{
if (instance == null) {
instance = new ParkingLot(numFloors);
}
return instance;
}
public ParkingTicket parkVehicle(Vehicle vehicle) {
for (ParkingFloor floor : floors) {
ParkingSpot spot =
[Link]([Link]());
if (spot != null) {
[Link]();
ParkingTicket ticket = new
ParkingTicket(spot);
[Link]([Link],
ticket);
[Link]([Link],
ticket);
[Link]("✅ Vehicle " +
[Link] + " parked.");
return ticket;
}
}
[Link]("🚫 No available spot for " +
[Link]);
return null;
}
public double exitVehicle(String numberPlate) {
ParkingTicket ticket =
[Link](numberPlate);
if (ticket != null) {
[Link]();
double fee = [Link]();
[Link]();
[Link]("🚗 Vehicle " +
numberPlate + " exited. Fee: $" + fee);
return fee;
}
[Link]("❌ Vehicle not found!");
return 0.0;
}
}
// Step 7: Testing the System
public class ParkingLotSystem {
public static void main(String[] args) {
ParkingLot lot = [Link](3);
Vehicle car = new Car("KA-01-AB-1234");
Vehicle bike = new Bike("KA-02-XY-5678");
ParkingTicket ticket1 = [Link](car);
ParkingTicket ticket2 = [Link](bike);
try { [Link](5000); } catch
(InterruptedException ignored) {} // Simulating time
[Link]("KA-01-AB-1234");
[Link]("KA-02-XY-5678");
}
}
✅ Supports multiple oors
✅ Supports di erent vehicle types
✅ Implements dynamic pricing
✅ Uses Singleton, Factory, Strategy, and State patterns
2⃣ Elevator System (Lift) 🏢
Design Patterns Used:
• Singleton → To manage a central controller for elevators
• Observer → To notify floors when an elevator arrives
• State → To track elevator status (Moving Up, Moving Down, Idle)
• Command → To queue requests for different floors
• Strategy → To optimize the elevator request handling (FIFO,
Nearest First)
🔗 Popular Question:
• Design an elevator system for a building with multiple floors and
elevators.
+-------------------+
| Elevator |
|-------------------|
ff
fl
|-------------------|
| + id |
| + currentFloor |
| + direction |
| + state |
| + move() |
| + openDoor() |
| + closeDoor() |
+-------------------+
|
| Implements
↓
+---------------------+
| RequestHandler |
|---------------------|
| + handleRequest() |
+---------------------+
+---------------------+
| ElevatorSystem |
|---------------------|
| + elevators[] |
| + requestQueue |
| + assignElevator() |
+---------------------+
+--------------------+
| ElevatorRequest |
|--------------------|
| + sourceFloor |
| + destinationFloor|
| + direction |
+--------------------+
+---------------------+
| FloorButton |
|---------------------|
| + pressUp() |
| + pressDown() |
+---------------------+
+----------------------+
| Display |
|----------------------|
| + showFloor() |
+----------------------+
import [Link].*;
// Enum for Elevator Direction
enum Direction { UP, DOWN, IDLE }
// Enum for Elevator State
enum ElevatorState { MOVING, IDLE, DOOR_OPEN }
// Elevator Request Model
class ElevatorRequest {
int sourceFloor;
int destinationFloor;
Direction direction;
public ElevatorRequest(int source, int dest) {
[Link] = source;
[Link] = dest;
[Link] = source < dest ? [Link] :
[Link];
}
}
// Elevator Class
class Elevator {
private int id;
private int currentFloor;
private Direction direction;
private ElevatorState state;
private Queue<ElevatorRequest> requestQueue;
public Elevator(int id) {
[Link] = id;
[Link] = 0;
[Link] = [Link];
[Link] = [Link];
[Link] = new LinkedList<>();
}
public int getCurrentFloor() { return
currentFloor; }
public Direction getDirection() { return
direction; }
public boolean isIdle() { return direction ==
[Link]; }
public void addRequest(ElevatorRequest request) {
[Link](request);
if (direction == [Link]) {
processNextRequest();
}
}
private void processNextRequest() {
if ([Link]()) {
direction = [Link];
return;
}
ElevatorRequest request = [Link]();
moveTo([Link]);
openDoor();
moveTo([Link]);
openDoor();
}
private void moveTo(int floor) {
[Link]("🚀 Elevator " + id + "
moving to floor " + floor);
[Link] = floor;
}
private void openDoor() {
[Link]("🚪 Elevator " + id + " doors
opening at floor " + currentFloor);
try { [Link](1000); } catch
(InterruptedException ignored) {}
[Link]("🚪 Elevator " + id + " doors
closing");
}
}
// Elevator Controller (Singleton)
class ElevatorSystem {
private static ElevatorSystem instance;
private List<Elevator> elevators;
private Queue<ElevatorRequest> requestQueue;
private ElevatorSystem(int numElevators) {
elevators = new ArrayList<>();
requestQueue = new LinkedList<>();
for (int i = 0; i < numElevators; i++) {
[Link](new Elevator(i + 1));
}
}
public static ElevatorSystem getInstance(int
numElevators) {
if (instance == null) {
instance = new ElevatorSystem(numElevators);
}
return instance;
}
public void requestElevator(int source, int dest) {
ElevatorRequest request = new
ElevatorRequest(source, dest);
Elevator bestElevator =
findBestElevator(request);
if (bestElevator != null) {
[Link](request);
} else {
[Link](request);
}
}
private Elevator findBestElevator(ElevatorRequest
request) {
for (Elevator elevator : elevators) {
if ([Link]()) return elevator;
}
return null;
}
}
// Floor Buttons
class FloorButton {
private int floor;
private ElevatorSystem system;
public FloorButton(int floor, ElevatorSystem system)
{
[Link] = floor;
[Link] = system;
}
public void pressUp(int destination) {
[Link]("🔼 Up button pressed at
floor " + floor);
[Link](floor, destination);
}
public void pressDown(int destination) {
[Link]("🔽 Down button pressed at
floor " + floor);
[Link](floor, destination);
}
}
// Display Panel
class Display {
public static void showFloor(int elevatorId, int
floor) {
[Link]("📟 Elevator " + elevatorId +
" is at floor " + floor);
}
}
// Main Class for Testing
public class ElevatorControlSystem {
public static void main(String[] args) {
ElevatorSystem system =
[Link](2);
FloorButton button1 = new FloorButton(1,
system);
FloorButton button5 = new FloorButton(5,
system);
[Link](5);
[Link](2);
try { [Link](5000); } catch
(InterruptedException ignored) {}
try { [Link](5000); } catch
(InterruptedException ignored) {}
[Link](7);
}
}
✅ Supports multiple elevators
✅ Handles up and down requests separately
✅ Optimized elevator assignment
✅ Implements Singleton, State, Strategy, and Observer patterns
3⃣ Chess Game ♟
Design Patterns Used:
• Factory → To create different types of chess pieces
• Strategy → To handle different movement rules for pieces
• Command → To execute and undo moves
• Observer → To notify players of check/checkmate conditions
• Memento → To save and restore game states (Undo/Redo feature)
🔗 Popular Question:
• Design a chess game that allows two players to play, validate
moves, and detect checkmate.
+-------------------+
| ChessGame |
| ChessGame |
|-------------------|
| + board |
| + players |
| + turn |
| + isCheckmate() |
| + makeMove() |
+-------------------+
+---------------------+
| ChessBoard |
|---------------------|
| + board[][] |
| + movePiece() |
| + isKingInCheck() |
+---------------------+
+---------------------+
| Player |
|---------------------|
| + name |
| + color |
+---------------------+
+---------------------+
| Piece |
|---------------------|
| + position |
| + color |
| + isValidMove() |
+---------------------+
|
| Inheritance
↓
+---------------------+
| Pawn |
+---------------------+
| Knight |
+---------------------+
| Bishop |
+---------------------+
| Rook |
+---------------------+
| Queen |
+---------------------+
| King |
+---------------------+
import [Link].*;
// Enum for Piece Color
enum Color { WHITE, BLACK }
// Position class to represent coordinates
class Position {
int row, col;
public Position(int row, int col) { [Link] = row;
[Link] = col; }
}
// Abstract Piece class
abstract class Piece {
protected Color color;
protected Position position;
public Piece(Color color, Position position) {
[Link] = color;
[Link] = position;
}
public Color getColor() { return color; }
public abstract boolean isValidMove(Position
newPosition, Piece[][] board);
}
// Pawn Implementation
class Pawn extends Piece {
public Pawn(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
int dir = (color == [Link]) ? -1 : 1;
return ([Link] == [Link] + dir) &&
([Link] == [Link]);
}
}
// Rook Implementation
class Rook extends Piece {
public Rook(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
return [Link] == [Link] ||
[Link] == [Link];
}
}
// Knight Implementation
class Knight extends Piece {
public Knight(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
int dx = [Link]([Link] - [Link]);
int dy = [Link]([Link] - [Link]);
return (dx == 2 && dy == 1) || (dx == 1 && dy ==
2);
}
}
// Bishop Implementation
class Bishop extends Piece {
public Bishop(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
return [Link]([Link] - [Link]) ==
[Link]([Link] - [Link]);
}
}
// Queen Implementation
class Queen extends Piece {
public Queen(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
return (new Rook(color,
position).isValidMove(newPos, board)) ||
(new Bishop(color,
position).isValidMove(newPos, board));
}
}
// King Implementation
class King extends Piece {
public King(Color color, Position position)
{ super(color, position); }
@Override
public boolean isValidMove(Position newPos, Piece[]
[] board) {
int dx = [Link]([Link] - [Link]);
int dy = [Link]([Link] - [Link]);
return (dx <= 1 && dy <= 1);
}
}
// Player class
class Player {
private String name;
private Color color;
public Player(String name, Color color) {
[Link] = name;
[Link] = color;
}
public Color getColor() { return color; }
}
// Chess Board Class (Singleton)
class ChessBoard {
private static ChessBoard instance;
private Piece[][] board;
private ChessBoard() {
board = new Piece[8][8];
initializeBoard();
}
public static ChessBoard getInstance() {
if (instance == null) {
instance = new ChessBoard();
}
return instance;
}
private void initializeBoard() {
// Placing pawns
for (int i = 0; i < 8; i++) {
board[1][i] = new Pawn([Link], new
Position(1, i));
board[6][i] = new Pawn([Link], new
Position(6, i));
}
// Placing rooks
board[0][0] = new Rook([Link], new
Position(0, 0));
board[0][7] = new Rook([Link], new
Position(0, 7));
board[7][0] = new Rook([Link], new
Position(7, 0));
board[7][7] = new Rook([Link], new
Position(7, 7));
// Placing knights
board[0][1] = new Knight([Link], new
Position(0, 1));
board[0][6] = new Knight([Link], new
Position(0, 6));
board[7][1] = new Knight([Link], new
Position(7, 1));
board[7][6] = new Knight([Link], new
Position(7, 6));
// Placing bishops
board[0][2] = new Bishop([Link], new
Position(0, 2));
board[0][5] = new Bishop([Link], new
Position(0, 5));
board[7][2] = new Bishop([Link], new
Position(7, 2));
board[7][5] = new Bishop([Link], new
Position(7, 5));
// Placing queens
board[0][3] = new Queen([Link], new
Position(0, 3));
board[7][3] = new Queen([Link], new
Position(7, 3));
// Placing kings
board[0][4] = new King([Link], new
Position(0, 4));
board[7][4] = new King([Link], new
Position(7, 4));
}
public boolean movePiece(Position from, Position to)
{
Piece piece = board[[Link]][[Link]];
if (piece == null || ) return false;
board[[Link]][[Link]] = piece;
board[[Link]][[Link]] = null;
return true;
}
}
// Main Game
public class ChessGame {
public static void main(String[] args) {
ChessBoard board = [Link]();
[Link](new Position(6, 4), new
Position(4, 4)); // Move White Pawn
[Link](new Position(1, 4), new
Position(3, 4)); // Move Black Pawn
}
}
✅ Supports all chess pieces
✅ Validates legal moves
✅ Uses Singleton, Factory, Strategy, and Observer patterns
✅ Handles turn-based play
4⃣ Tic-Tac-Toe / Connect Four 🎲
Design Patterns Used:
• Factory → To create different types of players (AI, Human)
• Strategy → For different winning strategies (Minimax for AI)
• Observer → To notify players when the game state changes
🔗 Popular Question:
• Design a Tic-Tac-Toe game where two players can play on a 3x3
board.
+-----------------+
| TicTacToe |
|-----------------|
| + board |
| + players |
| + turn |
| + playMove() |
| + checkWin() |
| + isDraw() |
+-----------------+
+-----------------+
+-----------------+
| Player |
|-----------------|
| + name |
| + symbol |
+-----------------+
+-----------------+
| Board |
|-----------------|
| + grid[][] |
| + printBoard() |
| + isFull() |
+-----------------+
import [Link];
// Enum for Cell State
enum Cell { EMPTY, X, O }
// Player Class
class Player {
private String name;
private Cell symbol;
public Player(String name, Cell symbol) {
[Link] = name;
[Link] = symbol;
}
public String getName() { return name; }
public Cell getSymbol() { return symbol; }
}
// Board Class
class Board {
private final int SIZE = 3;
private Cell[][] grid;
public Board() {
grid = new Cell[SIZE][SIZE];
for (int i = 0; i < SIZE; i++)
for (int j = 0; j < SIZE; j++)
grid[i][j] = [Link];
}
public void printBoard() {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
[Link](grid[i][j] ==
[Link] ? "-" : grid[i][j]);
[Link](" ");
}
[Link]();
}
}
public boolean placeMove(int row, int col, Cell
symbol) {
if (grid[row][col] == [Link]) {
grid[row][col] = symbol;
return true;
}
return false;
}
public boolean isFull() {
for (int i = 0; i < SIZE; i++)
for (int j = 0; j < SIZE; j++)
if (grid[i][j] == [Link]) return
false;
return true;
}
public boolean checkWin(Cell symbol) {
// Check rows and columns
for (int i = 0; i < SIZE; i++) {
if ((grid[i][0] == symbol && grid[i][1] ==
symbol && grid[i][2] == symbol) ||
(grid[0][i] == symbol && grid[1][i] ==
symbol && grid[2][i] == symbol)) {
return true;
}
}
// Check diagonals
return (grid[0][0] == symbol && grid[1][1] ==
symbol && grid[2][2] == symbol) ||
(grid[0][2] == symbol && grid[1][1] ==
symbol && grid[2][0] == symbol);
}
}
// Game Controller
public class TicTacToe {
private Board board;
private Player player1, player2;
private Player currentPlayer;
private Scanner scanner;
public TicTacToe() {
scanner = new Scanner([Link]);
}
public void startGame() {
[Link]("Enter Player 1 Name: ");
String p1 = [Link]();
[Link]("Enter Player 2 Name: ");
String p2 = [Link]();
player1 = new Player(p1, Cell.X);
player2 = new Player(p2, Cell.O);
currentPlayer = player1;
board = new Board();
[Link]();
while (true) {
[Link]([Link]() +
"'s Turn (" + [Link]() + ")");
[Link]("Enter row and column
(0-2): ");
int row = [Link]();
int col = [Link]();
if (row < 0 || row > 2 || col < 0 || col > 2
|| )) {
[Link]("Invalid move! Try
again.");
continue;
}
[Link]();
if
([Link]([Link]())) {
[Link]("🎉 " +
[Link]() + " Wins! 🎉 ");
break;
}
if ([Link]()) {
[Link]("It's a Draw! 🤝 ");
break;
}
currentPlayer = (currentPlayer == player1) ?
player2 : player1;
}
[Link]("Game Over!");
}
public static void main(String[] args) {
TicTacToe game = new TicTacToe();
[Link]();
}
}
✅ Supports two players with names
✅ Ensures valid moves only
✅ Detects win and draw conditions
✅ Uses Singleton, Factory, and Observer patterns
✅ Prints updated board after every move
⸻
5⃣ ATM System 🏧
Design Patterns Used:
• Chain of Responsibility → To handle different transaction requests
(Withdraw, Deposit, Balance Inquiry)
• State → To track ATM states (Idle, Processing, Out of Cash)
• Factory → To create different types of accounts (Savings,
Checking)
• Proxy → To verify authentication before allowing access
🔗 Popular Question:
• Design an ATM system where users can withdraw and deposit
money.
+------------------+
| ATM |
|------------------|
| - cashAvailable |
| - currentState |
| + insertCard() |
| + enterPIN() |
| + withdraw() |
| + deposit() |
+------------------+
+------------------+
| ATMState | (Interface)
|------------------|
| + insertCard() |
| + enterPIN() |
| + enterPIN() |
| + withdraw() |
| + deposit() |
+------------------+
|
| Implements
|
+------------------+ +------------------+
| IdleState | | CardInserted |
+------------------+ +------------------+
| + insertCard() | | + enterPIN() |
+------------------+ +------------------+
+------------------+ +------------------+
| PinVerified | | TransactionState |
+------------------+ +------------------+
| + withdraw() | | + withdraw() |
| + deposit() | | + deposit() |
+------------------+ +------------------+
+------------------+
| Account |
|------------------|
| - balance |
| + deposit() |
| + withdraw() |
+------------------+
import [Link];
// Account class
class Account {
private int balance;
private int pin;
public Account(int balance, int pin) {
[Link] = balance;
[Link] = pin;
}
public boolean validatePin(int enteredPin) {
return [Link] == enteredPin;
}
public boolean withdraw(int amount) {
if (amount > balance) {
[Link]("❌ Insufficient
Funds!");
return false;
}
balance -= amount;
[Link]("✅ Withdrawal Successful!
New Balance: $" + balance);
return true;
}
public void deposit(int amount) {
balance += amount;
[Link]("✅ Deposit Successful! New
Balance: $" + balance);
}
public int getBalance() {
return balance;
}
}
// ATM State Interface
interface ATMState {
void insertCard();
void enterPIN(int pin);
void withdraw(int amount);
void deposit(int amount);
void ejectCard();
}
// Idle State
class IdleState implements ATMState {
private ATM atm;
public IdleState(ATM atm) {
[Link] = atm;
}
@Override
public void insertCard() {
[Link]("💳 Card Inserted.");
[Link]([Link]());
}
@Override
public void enterPIN(int pin) {
[Link]("❌ Insert card first.");
}
@Override
public void withdraw(int amount) {
[Link]("❌ Insert card first.");
}
@Override
public void deposit(int amount) {
[Link]("❌ Insert card first.");
}
@Override
public void ejectCard() {
[Link]("❌ No card to eject.");
}
}
// Card Inserted State
class CardInsertedState implements ATMState {
private ATM atm;
public CardInsertedState(ATM atm) {
[Link] = atm;
}
@Override
public void insertCard() {
[Link]("❌ Card already inserted.");
}
@Override
public void enterPIN(int pin) {
if ([Link]().validatePin(pin)) {
[Link]("✅ PIN Verified!");
[Link]([Link]());
} else {
[Link]("❌ Incorrect PIN. Try
Again.");
[Link]("❌ Incorrect PIN. Try
Again.");
}
}
@Override
public void withdraw(int amount) {
[Link]("❌ Enter PIN first.");
}
@Override
public void deposit(int amount) {
[Link]("❌ Enter PIN first.");
}
@Override
public void ejectCard() {
[Link]("💳 Card Ejected.");
[Link]([Link]());
}
}
// PIN Verified State
class PinVerifiedState implements ATMState {
private ATM atm;
public PinVerifiedState(ATM atm) {
[Link] = atm;
}
@Override
public void insertCard() {
[Link]("❌ Card already inserted.");
}
@Override
public void enterPIN(int pin) {
[Link]("❌ PIN already verified.");
}
@Override
public void withdraw(int amount) {
if ([Link]() >= amount &&
[Link]().withdraw(amount)) {
[Link](amount);
} else {
[Link]("❌ ATM has insufficient
cash.");
}
}
@Override
public void deposit(int amount) {
[Link]().deposit(amount);
}
@Override
public void ejectCard() {
[Link]("💳 Card Ejected.");
[Link]([Link]());
}
}
// ATM Class (Singleton)
class ATM {
private static ATM instance;
private int cashAvailable;
private Account account;
private ATMState currentState;
private ATMState idleState, cardInsertedState,
pinVerifiedState;
private ATM() {
[Link] = 10000; // ATM initially has
$10,000
[Link] = new IdleState(this);
[Link] = new
CardInsertedState(this);
[Link] = new
PinVerifiedState(this);
[Link] = idleState;
}
public static ATM getInstance() {
if (instance == null) instance = new ATM();
return instance;
}
public void setAccount(Account account) {
[Link] = account;
}
public Account getAccount() {
return account;
}
public void setState(ATMState state) {
[Link] = state;
}
public ATMState getIdleState() { return idleState; }
public ATMState getCardInsertedState() { return
cardInsertedState; }
public ATMState getPinVerifiedState() { return
pinVerifiedState; }
public int getCashAvailable() { return
cashAvailable; }
public void reduceCash(int amount) { cashAvailable
-= amount; }
public void insertCard()
{ [Link](); }
public void enterPIN(int pin)
{ [Link](pin); }
public void withdraw(int amount)
{ [Link](amount); }
public void deposit(int amount)
{ [Link](amount); }
public void ejectCard()
{ [Link](); }
}
// Main Program
public class ATMSystem {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
ATM atm = [Link]();
Account userAccount = new Account(5000,
1234); // User with $5000 balance and PIN 1234
[Link](userAccount);
[Link]();
[Link]("Enter PIN: ");
int pin = [Link]();
[Link](pin);
[Link]("Enter amount to withdraw: ");
int withdrawAmount = [Link]();
[Link](withdrawAmount);
[Link]("Enter amount to deposit: ");
int depositAmount = [Link]();
[Link](depositAmount);
[Link]();
[Link]();
}
}
✅ Uses State Pattern to manage ATM states.
✅ Ensures secure PIN authentication.
✅ Allows withdrawal and deposit operations.
✅ Supports Singleton ATM instance.
6⃣ Ride-Sharing System (Uber, Ola) 🚕
Design Patterns Used:
• Singleton → For a central ride-matching service
• Factory → To create different ride types (Economy, Premium,
Shared)
• Observer → To notify drivers and riders of trip updates
• Strategy → To calculate fare dynamically based on traffic, surge
pricing
• Strategy → To calculate fare dynamically based on traffic, surge
pricing
🔗 Popular Question:
• Design a ride-sharing app where users can book a ride, and drivers
can accept it.
+-------------------+
| User |
|-------------------|
| - userId |
| - name |
| - location |
| + requestRide() |
+-------------------+
+-------------------+
| Driver |
|-------------------|
| - driverId |
| - name |
| - location |
| - isAvailable |
| + acceptRide() |
+-------------------+
+-------------------+
| Ride |
|-------------------|
| - rideId |
| - user |
| - driver |
| - pickupLocation |
| - dropLocation |
| - status |
| + updateStatus() |
+-------------------+
+-------------------+
| RideMatcher |
|-------------------|
| - activeRides |
| - activeRides |
| + findDriver() |
| + notifyDrivers()|
+-------------------+
import [Link].*;
// Enum for Ride Status
enum RideStatus { REQUESTED, ACCEPTED, ONGOING,
COMPLETED, CANCELLED; }
// User Class
class User {
private int userId;
private String name;
private String location;
public User(int userId, String name, String
location) {
[Link] = userId;
[Link] = name;
[Link] = location;
}
public Ride requestRide(String dropLocation) {
[Link](name + " requested a ride
from " + location + " to " + dropLocation);
Ride ride = new Ride(this, dropLocation);
[Link]().notifyDrivers(ride);
return ride;
}
public String getLocation() {
return location;
}
public String getName() {
return name;
}
}
// Driver Class
class Driver {
private int driverId;
private String name;
private String location;
private boolean isAvailable;
public Driver(int driverId, String name, String
location) {
[Link] = driverId;
[Link] = name;
[Link] = location;
[Link] = true;
}
public void acceptRide(Ride ride) {
if (!isAvailable) {
[Link](name + " is not
available.");
return;
}
[Link]("🚗 " + name + " accepted the
ride for " + [Link]().getName());
[Link](this);
[Link]([Link]);
isAvailable = false;
}
public boolean isAvailable() {
return isAvailable;
}
public String getLocation() {
return location;
}
public String getName() {
return name;
}
}
// Ride Class
class Ride {
private static int rideCounter = 1;
private int rideId;
private User user;
private Driver driver;
private String pickupLocation;
private String dropLocation;
private RideStatus status;
public Ride(User user, String dropLocation) {
[Link] = rideCounter++;
[Link] = user;
[Link] = [Link]();
[Link] = dropLocation;
[Link] = [Link];
}
public void setDriver(Driver driver) {
[Link] = driver;
}
public void updateStatus(RideStatus newStatus) {
[Link] = newStatus;
[Link]("🚕 Ride " + rideId + " is
now " + newStatus);
}
public User getUser() {
return user;
}
public RideStatus getStatus() {
return status;
}
}
// Ride Matcher Singleton (Matches Rides to Drivers)
class RideMatcher {
private static RideMatcher instance;
private List<Driver> drivers;
private RideMatcher() {
[Link] = new ArrayList<>();
}
public static RideMatcher getInstance() {
if (instance == null) {
instance = new RideMatcher();
}
return instance;
}
public void registerDriver(Driver driver) {
[Link](driver);
}
public void notifyDrivers(Ride ride) {
for (Driver driver : drivers) {
if ([Link]()) {
[Link]("🔔 Notifying " +
[Link]() + " of a new ride request.");
}
}
}
public void findDriverForRide(Ride ride) {
for (Driver driver : drivers) {
if ([Link]()) {
[Link](ride);
return;
}
}
[Link]("❌ No available drivers at
the moment.");
}
}
// Main App
public class RideSharingApp {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
RideMatcher rideMatcher =
[Link]();
// Creating users and drivers
User user1 = new User(1, "Alice", "Downtown");
Driver driver1 = new Driver(101, "Bob",
"Downtown");
Driver driver2 = new Driver(102, "Charlie",
"Uptown");
// Registering drivers
[Link](driver1);
[Link](driver2);
// User requests a ride
Ride ride1 = [Link]("Airport");
// Finding driver
[Link](ride1);
// Simulating ride completion
if ([Link]() == [Link]) {
[Link]("🚖 Ride is now
ongoing...");
[Link]([Link]);
[Link]("Press Enter to complete
the ride...");
[Link]();
[Link]([Link]);
[Link]("✅ Ride Completed. Thank
you for using our service!");
}
[Link]();
}
}
✅ User requests a ride with a pickup and drop-off location.
✅ Drivers are noti ed of new ride requests.
✅ Drivers can accept rides and change ride status.
✅ Singleton Pattern ensures one ride-matching instance.
✅ Observer Pattern notifies drivers of new ride requests.
✅ State Pattern manages ride lifecycle transitions.
⸻
fi
7⃣ Hotel Booking System 🏨
Design Patterns Used:
• Singleton → To manage a central reservation system
• Factory → To create different room types (Deluxe, Suite, Standard)
• Observer → To notify users of booking confirmations
• Decorator → To add optional features like Wi-Fi, breakfast, spa
services
🔗 Popular Question:
• Design a hotel booking system where users can search and book
available rooms.
+-------------------+
| User |
|-------------------|
| - userId |
| - name |
| - email |
| + searchRooms() |
| + bookRoom() |
+-------------------+
+-------------------+
| Hotel |
|-------------------|
| - hotelId |
| - name |
| - location |
| - rooms |
| + addRoom() |
| + addRoom() |
| + getAvailableRooms() |
+-------------------+
+-------------------+
| Room |
|-------------------|
| - roomId |
| - type |
| - price |
| - isAvailable |
| + book() |
| + cancelBooking()|
+-------------------+
+-------------------+
| BookingManager |
|-------------------|
| - bookings |
| + bookRoom() |
| + cancelBooking()|
+-------------------+
import [Link].*;
// Enum for Room Types
enum RoomType { SINGLE, DOUBLE, SUITE; }
// Room Factory (Factory Pattern)
class RoomFactory {
public static Room createRoom(int roomId, RoomType
type) {
switch (type) {
case SINGLE: return new Room(roomId, type,
100);
case DOUBLE: return new Room(roomId, type,
200);
case SUITE: return new Room(roomId, type,
500);
default: throw new
IllegalArgumentException("Invalid Room Type");
}
}
}
// Room Class
class Room {
private int roomId;
private RoomType type;
private double price;
private boolean isAvailable;
public Room(int roomId, RoomType type, double price)
{
[Link] = roomId;
[Link] = type;
[Link] = price;
[Link] = true;
}
public boolean isAvailable() {
return isAvailable;
}
public void book() {
if (isAvailable) {
isAvailable = false;
[Link]("✅ Room " + roomId + "
booked successfully.");
} else {
[Link]("❌ Room " + roomId + "
is already booked.");
}
}
public void cancelBooking() {
isAvailable = true;
[Link]("🔄 Room " + roomId + "
booking canceled.");
}
public RoomType getType() {
return type;
}
public int getRoomId() {
return roomId;
}
}
// Hotel Class
class Hotel {
private int hotelId;
private String name;
private String location;
private List<Room> rooms;
public Hotel(int hotelId, String name, String
location) {
[Link] = hotelId;
[Link] = name;
[Link] = location;
[Link] = new ArrayList<>();
}
public void addRoom(Room room) {
[Link](room);
}
public List<Room> getAvailableRooms(RoomType type) {
List<Room> availableRooms = new ArrayList<>();
for (Room room : rooms) {
if ([Link]() && [Link]() ==
type) {
[Link](room);
}
}
return availableRooms;
}
public String getName() {
return name;
}
public String getLocation() {
return location;
}
}
// User Class
class User {
private int userId;
private String name;
private String email;
public User(int userId, String name, String email) {
[Link] = userId;
[Link] = name;
[Link] = email;
}
public List<Room> searchRooms(Hotel hotel, RoomType
type) {
List<Room> availableRooms =
[Link](type);
[Link]("🔍 Found " +
[Link]() + " available rooms in " +
[Link]());
return availableRooms;
}
public void bookRoom(BookingManager bookingManager,
Room room) {
[Link](this, room);
}
}
// Booking Manager (Singleton Pattern)
class BookingManager {
private static BookingManager instance;
private Map<Integer, User> bookings;
private BookingManager() {
bookings = new HashMap<>();
}
public static BookingManager getInstance() {
if (instance == null) {
instance = new BookingManager();
}
return instance;
}
public void bookRoom(User user, Room room) {
if (![Link]()) {
[Link]("❌ Booking failed! Room
" + [Link]() + " is already booked.");
return;
}
[Link]();
[Link]([Link](), user);
[Link]("📢 Booking confirmed for " +
[Link]);
}
public void cancelBooking(Room room) {
if ()) {
[Link]("❌ No booking found for
Room " + [Link]());
return;
}
[Link]();
[Link]([Link]());
[Link]("✅ Booking canceled
successfully.");
}
}
// Main App
public class HotelBookingApp {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
BookingManager bookingManager =
[Link]();
// Creating Hotel and Rooms
Hotel hotel = new Hotel(1, "Grand Palace", "New
York");
Room room1 = [Link](101,
[Link]);
Room room2 = [Link](102,
[Link]);
Room room3 = [Link](103,
[Link]);
[Link](room1);
[Link](room2);
[Link](room3);
// Creating Users
User user1 = new User(1, "Alice",
"alice@[Link]");
// Searching Rooms
List<Room> availableRooms =
[Link](hotel, [Link]);
// Booking a Room
if (![Link]()) {
[Link](bookingManager,
[Link](0));
}
// Simulating cancellation
[Link]("Press Enter to cancel
booking...");
[Link]();
[Link](room2);
[Link]();
}
}
✅ Users can search for available rooms based on type.
✅ Users can book a room if it s available.
✅ Prevents double booking of rooms.
✅ Users can cancel bookings.
✅ Factory Pattern ensures correct room types are created.
✅ Singleton Pattern ensures a single booking manager instance.
✅ Observer Pattern can be extended for notifications.
8⃣ Vending Machine System 🥤
’
Design Patterns Used:
• State → To track vending machine states (Waiting, Payment
Received, Dispensing)
• Factory → To create different product types (Soda, Chips, Candy)
• Command → To handle different user actions (Insert Coin, Select
Product, Cancel)
🔗 Popular Question:
• Design a vending machine that allows users to buy drinks and
snacks.
+-------------------+
| VendingMachine |
|-------------------|
| - inventory |
| - balance |
| - state |
| + insertCoin() |
| + selectItem() |
| + dispenseItem()|
+-------------------+
+-------------------+
| Item |
|-------------------|
| - name |
| - price |
| + getPrice() |
+-------------------+
+-------------------+
| ItemFactory |
|-------------------|
|-------------------|
| + createItem() |
+-------------------+
+-------------------+
| State |
|-------------------|
| + insertCoin() |
| + selectItem() |
| + dispenseItem() |
+-------------------+
// Enum for Machine States
enum MachineState { IDLE, SELECTING, DISPENSING; }
// Enum for Item Types
enum ItemType { DRINK, SNACK; }
// Item Class
class Item {
private String name;
private double price;
public Item(String name, double price) {
[Link] = name;
[Link] = price;
}
public double getPrice() {
return price;
}
public String getName() {
return name;
}
}
// Item Factory (Factory Pattern)
class ItemFactory {
public static Item createItem(String name, ItemType
type) {
if (type == [Link]) return new
Item(name, 2.50);
else if (type == [Link]) return new
Item(name, 1.50);
else if (type == [Link]) return new
Item(name, 1.50);
throw new IllegalArgumentException("Invalid Item
Type");
}
}
// State Interface (State Pattern)
interface VendingState {
void insertCoin(double amount);
void selectItem(String itemName);
void dispenseItem();
}
// Vending Machine Class
class VendingMachine {
private Map<String, Item> inventory = new
HashMap<>();
private double balance = 0;
private VendingState state;
public VendingMachine() {
[Link] = new IdleState(this);
[Link]("Coke",
[Link]("Coke", [Link]));
[Link]("Chips",
[Link]("Chips", [Link]));
}
public void setState(VendingState state) {
[Link] = state;
}
public void insertCoin(double amount) {
[Link](amount);
}
public void selectItem(String itemName) {
[Link](itemName);
}
public void dispenseItem() {
[Link]();
}
public double getBalance() {
return balance;
}
public void addBalance(double amount) {
balance += amount;
}
public void resetBalance() {
balance = 0;
}
public boolean hasItem(String name) {
return [Link](name);
}
public Item getItem(String name) {
return [Link](name);
}
}
// Idle State
class IdleState implements VendingState {
private VendingMachine machine;
public IdleState(VendingMachine machine) {
[Link] = machine;
}
public void insertCoin(double amount) {
[Link](amount);
[Link]("💰 Coin inserted: $" +
amount);
[Link](new SelectingState(machine));
}
public void selectItem(String itemName) {
[Link]("❌ Please insert coins
first.");
}
public void dispenseItem() {
[Link]("❌ No item selected.");
}
}
// Selecting State
class SelectingState implements VendingState {
private VendingMachine machine;
public SelectingState(VendingMachine machine) {
[Link] = machine;
}
public void insertCoin(double amount) {
[Link](amount);
[Link]("💰 Additional coin inserted:
$" + amount);
}
public void selectItem(String itemName) {
if () {
[Link]("❌ Item not
available.");
return;
}
Item item = [Link](itemName);
if ([Link]() < [Link]()) {
[Link]("❌ Not enough money!
Insert $" + ([Link]() - [Link]()) + "
more.");
} else {
[Link]("✅ Item selected: " +
[Link]());
[Link](new
DispensingState(machine, item));
}
}
public void dispenseItem() {
[Link]("❌ Please select an item
first.");
}
}
// Dispensing State
class DispensingState implements VendingState {
private VendingMachine machine;
private Item item;
public DispensingState(VendingMachine machine, Item
item) {
[Link] = machine;
[Link] = item;
}
public void insertCoin(double amount) {
[Link]("❌ Transaction in progress.
Please wait.");
}
public void selectItem(String itemName) {
[Link]("❌ Dispensing in
progress...");
}
public void dispenseItem() {
[Link]("🛒 Dispensing: " +
[Link]());
double change = [Link]() -
[Link]();
if (change > 0) {
[Link]("💰 Returning change: $"
+ change);
}
[Link]();
[Link](new IdleState(machine));
}
}
// Main App
public class VendingMachineApp {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
VendingMachine vendingMachine = new
VendingMachine();
[Link]("🛒 Vending Machine Ready!");
[Link]("Available items: Coke
($2.50), Chips ($1.50)");
while (true) {
[Link]("\nOptions: 1. Insert
Coin 2. Select Item 3. Dispense Item 4. Exit");
[Link]("Choose an option: ");
int choice = [Link]();
if (choice == 1) {
[Link]("Enter amount: ");
double amount = [Link]();
[Link](amount);
} else if (choice == 2) {
[Link]("Enter item name: ");
String itemName = [Link]();
[Link](itemName);
} else if (choice == 3) {
[Link]();
} else {
[Link]("🚪 Exiting vending
machine...");
break;
}
}
[Link]();
}
}
✅ Users can insert coins.
✅ Users can select items if they have enough balance.
✅ Prevents selection if funds are insu cient.
✅ Dispenses item and returns change.
✅ Implements State Pattern for di erent vending machine states.
✅ Uses Factory Pattern for item creation.
9⃣ Amazon/Flipkart Checkout System 🛒
Design Patterns Used:
ff
ffi
Design Patterns Used:
• Strategy → For different payment methods (Credit Card, PayPal,
UPI)
• Observer → To notify users about order status updates
• Decorator → To add optional services (Gift Wrap, Fast Delivery)
• Proxy → To validate user authentication before checkout
🔗 Popular Question:
• Design an e-commerce checkout system that allows users to
purchase items online.
+------------------+
| Product |
|------------------|
| - id |
| - name |
| - price |
| + getPrice() |
+------------------+
+------------------+
| CartItem |
|------------------|
| - product |
| - quantity |
| + getTotal() |
+------------------+
+------------------+
| Cart |
|------------------|
| - items |
| + addItem() |
| + addItem() |
| + removeItem() |
| + getTotal() |
+------------------+
+------------------+
| PaymentMethod |
|------------------|
| + pay(amount) |
+------------------+
+------------------+
| OrderService |
|------------------|
| + checkout() |
+------------------+
+------------------+
| OrderObserver |
|------------------|
| + notify() |
+------------------+
class Product {
private String id;
private String name;
private double price;
public Product(String id, String name, double price)
{
[Link] = id;
[Link] = name;
[Link] = price;
}
public double getPrice() {
return price;
}
public String getName() {
return name;
}
}
// Cart Item
class CartItem {
private Product product;
private int quantity;
public CartItem(Product product, int quantity) {
[Link] = product;
[Link] = quantity;
}
public double getTotal() {
return [Link]() * quantity;
}
public Product getProduct() {
return product;
}
public int getQuantity() {
return quantity;
}
}
// Cart Class
class Cart {
private List<CartItem> items = new ArrayList<>();
public void addItem(Product product, int quantity) {
[Link](new CartItem(product, quantity));
[Link]("🛒 Added: " +
[Link]() + " x" + quantity);
}
public void removeItem(String productName) {
[Link](item ->
[Link]().getName().equals(productName));
[Link]("❌ Removed: " +
productName);
}
public double getTotal() {
return
[Link]().mapToDouble(CartItem::getTotal).sum();
}
public List<CartItem> getItems() {
return items;
}
}
// Payment Strategy
interface PaymentMethod {
void pay(double amount);
}
// Credit Card Payment
class CreditCardPayment implements PaymentMethod {
public void pay(double amount) {
[Link]("💳 Paid $" + amount + "
using Credit Card.");
}
}
// PayPal Payment
class PayPalPayment implements PaymentMethod {
public void pay(double amount) {
[Link]("📧 Paid $" + amount + "
using PayPal.");
}
}
// UPI Payment
class UpiPayment implements PaymentMethod {
public void pay(double amount) {
[Link]("📱 Paid $" + amount + "
using UPI.");
}
}
// Observer Interface
interface OrderObserver {
void notify(String message);
}
// Email Notification
class EmailNotification implements OrderObserver {
public void notify(String message) {
[Link]("📩 Email: " + message);
}
}
// SMS Notification
class SMSNotification implements OrderObserver {
public void notify(String message) {
[Link]("📲 SMS: " + message);
}
}
// Order Service (Handles Checkout)
class OrderService {
private Cart cart;
private List<OrderObserver> observers = new
ArrayList<>();
public OrderService(Cart cart) {
[Link] = cart;
}
public void addObserver(OrderObserver observer) {
[Link](observer);
}
public void checkout(PaymentMethod paymentMethod) {
if ([Link]().isEmpty()) {
[Link]("❌ Cart is empty. Cannot
checkout.");
return;
}
double totalAmount = [Link]();
[Link](totalAmount);
String confirmation = "✅ Order placed! Total:
$" + totalAmount;
[Link](observer ->
[Link](confirmation));
}
}
// Main Application
public class ECommerceCheckout {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
Cart cart = new Cart();
OrderService orderService = new
OrderService(cart);
// Adding Notification Observers
[Link](new
EmailNotification());
[Link](new SMSNotification());
// Available Products
Product phone = new Product("P1001",
"Smartphone", 599.99);
Product laptop = new Product("P2001", "Laptop",
999.99);
Product headphones = new Product("P3001",
"Headphones", 199.99);
// User Interaction
while (true) {
[Link]("\nOptions: 1. Add to
Cart 2. Remove Item 3. Checkout 4. Exit");
[Link]("Choose an option: ");
int choice = [Link]();
if (choice == 1) {
[Link]("Available Products:
1. Smartphone ($599.99) 2. Laptop ($999.99) 3.
Headphones ($199.99)");
[Link]("Select product (1-3):
");
int productChoice = [Link]();
[Link]("Enter quantity: ");
int quantity = [Link]();
switch (productChoice) {
case 1 -> [Link](phone,
quantity);
case 2 -> [Link](laptop,
quantity);
case 3 -> [Link](headphones,
quantity);
default -> [Link]("❌
Invalid choice.");
default -> [Link]("❌
Invalid choice.");
}
}
else if (choice == 2) {
[Link]("Enter product name to
remove: ");
[Link](); // Consume newline
String productName = [Link]();
[Link](productName);
}
else if (choice == 3) {
[Link]("Payment Options: 1.
Credit Card 2. PayPal 3. UPI");
[Link]("Select payment method:
");
int paymentChoice = [Link]();
PaymentMethod paymentMethod = switch
(paymentChoice) {
case 1 -> new CreditCardPayment();
case 2 -> new PayPalPayment();
case 3 -> new UpiPayment();
default -> {
[Link]("❌ Invalid
choice. Defaulting to Credit Card.");
yield new CreditCardPayment();
}
};
[Link](paymentMethod);
}
else {
[Link]("🚪 Exiting...");
break;
}
}
[Link]();
}
}
✅ Users can add/remove items from the cart.
✅ Multiple payment methods (Credit Card, PayPal, UPI).
✅ Validates empty cart before checkout.
✅ Validates empty cart before checkout.
✅ Implements Observer Pattern to send order noti cations.
✅ Uses Strategy Pattern for di erent payment methods.
✅ Checkout con rms the order and payment.
🔟 Multi-Player Card Game (Poker, Blackjack) 🃏
Design Patterns Used:
• Factory → To create different card types (Spades, Hearts,
Diamonds, Clubs)
• Strategy → To handle different game rules (Poker, Rummy,
Blackjack)
• Observer → To notify players of game events
• Memento → To save and restore game states
🔗 Popular Question:
• Design a multi-player Poker game where players can place bets,
fold, and win rounds.
+------------------+
| Player |
|------------------|
| - id |
| - name |
| - balance |
| - hand |
| + bet() |
fi
ff
fi
| + bet() |
| + fold() |
+------------------+
+------------------+
| Card |
|------------------|
| - rank |
| - suit |
+------------------+
+------------------+
| Deck |
|------------------|
| - cards |
| + shuffle() |
| + dealCard() |
+------------------+
+------------------+
| PokerGame |
|------------------|
| - players |
| - deck |
| - pot |
| - state |
| + startRound() |
| + nextPhase() |
| + determineWinner() |
+------------------+
+------------------+
| BettingState |
|------------------|
| + handleBet() |
+------------------+
// Card Representation
class Card {
enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES }
enum Rank { TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }
private final Rank rank;
private final Suit suit;
public Card(Rank rank, Suit suit) {
[Link] = rank;
[Link] = suit;
}
public Rank getRank() { return rank; }
public Suit getSuit() { return suit; }
@Override
public String toString() {
return rank + " of " + suit;
}
}
// Deck of Cards
class Deck {
private final List<Card> cards = new ArrayList<>();
private final Random random = new Random();
public Deck() {
for ([Link] suit : [Link]()) {
for ([Link] rank : [Link]()) {
[Link](new Card(rank, suit));
}
}
shuffle();
}
public void shuffle() {
[Link](cards, random);
}
public Card dealCard() {
return [Link]([Link]() - 1);
}
}
// Player Class
class Player {
private final String name;
private double balance;
private final List<Card> hand = new ArrayList<>();
private boolean folded = false;
public Player(String name, double balance) {
[Link] = name;
[Link] = balance;
}
public void receiveCard(Card card) {
[Link](card);
}
public void bet(double amount) {
if (amount <= balance) {
balance -= amount;
[Link](name + " bet $" +
amount);
} else {
[Link](name + " doesn't have
enough balance.");
}
}
public void fold() {
folded = true;
[Link](name + " folds.");
}
public boolean isFolded() {
return folded;
}
public double getBalance() {
return balance;
}
public List<Card> getHand() {
return hand;
}
public String getName() {
return name;
}
}
// Game State (Strategy Pattern)
interface BettingState {
void handleBet(Player player, double amount);
}
class PreFlopState implements BettingState {
public void handleBet(Player player, double amount)
{
[Link]("Pre-Flop: " +
[Link]() + " bets $" + amount);
[Link](amount);
}
}
class FlopState implements BettingState {
public void handleBet(Player player, double amount)
{
[Link]("Flop: " + [Link]() +
" bets $" + amount);
[Link](amount);
}
}
class TurnState implements BettingState {
public void handleBet(Player player, double amount)
{
[Link]("Turn: " + [Link]() +
" bets $" + amount);
[Link](amount);
}
}
class RiverState implements BettingState {
public void handleBet(Player player, double amount)
{
[Link]("River: " + [Link]()
+ " bets $" + amount);
[Link](amount);
}
}
// Poker Game
class PokerGame {
private final List<Player> players = new
ArrayList<>();