0% found this document useful (0 votes)
22 views68 pages

Multi-Level Parking Lot System Design

The document outlines three systems: a Parking Lot System, an Elevator System, and a Chess Game, each utilizing various design patterns such as Singleton, Factory, and Observer. The Parking Lot System manages vehicle parking with different spot types and pricing strategies, while the Elevator System coordinates multiple elevators and requests. The Chess Game allows two players to play with different chess pieces, validating moves and detecting check/checkmate conditions.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views68 pages

Multi-Level Parking Lot System Design

The document outlines three systems: a Parking Lot System, an Elevator System, and a Chess Game, each utilizing various design patterns such as Singleton, Factory, and Observer. The Parking Lot System manages vehicle parking with different spot types and pricing strategies, while the Elevator System coordinates multiple elevators and requests. The Chess Game allows two players to play with different chess pieces, validating moves and detecting check/checkmate conditions.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

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 || ![Link](to,
board)) 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](row, col,
[Link]())) {
[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]([Link]())) {
[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](itemName)) {
[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<>();

Common questions

Powered by AI

The Strategy pattern in fare calculation allows the ride-sharing application to adjust fares dynamically based on varying factors like traffic conditions, surge pricing, and ride type (economy, premium, shared). By encapsulating these calculation algorithms into interchangeable strategies, the system can offer adaptive pricing models that enhance service offerings. This adaptability optimizes fare charges in real-time and aligns them with demand fluctuations, ensuring competitive pricing and maximizing revenue. However, this can impact user experience by providing transparent and fair cost displays, leading to increased satisfaction through predictable transaction expectations, while potentially causing dissatisfaction if not communicated or perceived as fair .

The Factory pattern in the hotel booking system is employed to abstract and encapsulate the instantiation logic of room types, such as Single, Double, or Suite rooms. By centralizing room creation, the system ensures that only valid, predefined room configurations are established, maintaining consistency in room attributes and pricing structures. This distinction prevents illegal or unsupported room types that could disrupt booking processes, ensuring that all available rooms align with operational and service standards, thus protecting both customer expectations and the hotel's resource management .

The use of the Singleton pattern for the RideMatcher in a ride-sharing system centralizes ride-matching functions, ensuring all ride requests and driver assignments are processed through a unified entity. This architectural decision enhances efficiency by maintaining a single shared state and coordinating actions across the entire system, reducing inconsistencies and preventing redundant match logic. By consolidating control, the system minimizes latency issues and enables coordinated optimization measures, such as load balancing and priority handling, enhancing overall service reliability and response times .

The Observer pattern in the ride-sharing system is used to establish a scalable notification system where users and drivers are kept updated about ride statuses. When a ride request is made, the system notifies available drivers. Once a driver accepts the ride, the user is informed of the driver's details and status updates throughout the ride. This pattern decouples the system into observer components that react to changes in ride status, improving scalability over traditional direct function calls by allowing multiple observers to listen to changes and act independently. This flexibility suits dynamic environments like ride-sharing, where numerous users and drivers interact simultaneously .

The Singleton pattern ensures there is only one instance of the ChessBoard throughout the application's lifecycle, which is crucial for maintaining a consistent game state in a chess game. This pattern prevents multiple, potentially conflicting instances of the board from being created, which could lead to inconsistent game states and erroneous move validations. It also provides a global point of access to the ChessBoard, simplifying access from various components within the game architecture, such as players making moves or validating game conditions .

The Observer pattern in the chess game serves as a crucial mechanism for dynamically managing check/checkmate notifications. By using observers, changes in the board state trigger immediate notifications to players about critical conditions, allowing real-time updates and interventions. This approach enhances the accuracy of game logic by decoupling check detection and notification from move execution, reducing potential timing issues or missed notifications in complex game states. Additionally, it streamlines player interaction with automatic alerts, maintaining engagement and focus by alleviating manual checks by the players .

The Command pattern enhances the chess game's management of user actions by abstracting moves into discrete command objects. Each command encapsulates a move's logic, including execution and undo functionality. This separation facilitates flexible action management and consistent execution validation, creating a robust framework for processing complex sequences and reversing moves through undo operations. The pattern supports advanced gameplay features like move histories and game state restoration without convoluting the UI logic or game flow management, enhancing user control over gameplay and providing a seamless user experience .

The State pattern effectively manages the current state of the vending machine by encapsulating behaviors into separate classes for each state. This design allows the machine to transition cleanly between waiting for input, receiving payment, and dispensing items. By segregating the behaviors, the code for each state is more organized, easier to maintain, and extendable. The machine can react differently to inputs based on its current state, enhancing robustness and reducing the likelihood of errors when shifting states, such as avoiding item dispensing if payment has not been confirmed .

The Decorator pattern in an e-commerce checkout system allows seamless integration of optional services such as gift wrapping and fast delivery by wrapping additional functionality around core product purchases. This pattern circumvents rigid subclassing by enabling dynamic addition or removal of features at runtime, enhancing flexibility and user choice diversity. Customers can customize orders based on their preferences, increasing satisfaction by offering tailored options without complex modifications to the existing system's architecture. This approach also fosters modularity, allowing separate service logic management and iterative development without disrupting baseline operations .

The State pattern is well-suited for ATM systems as it provides a structured way to handle different transaction phases: waiting, processing, and completing. By encapsulating each state in its own class, the pattern allows distinct behaviors for each phase, such as card authentication, transaction processing, and finalizing steps, to be managed and switched seamlessly. This separation clarifies state-dependent logic, reduces complexity by preventing mixed-state code, and enhances maintenance and scalability. The ATM system thus becomes more robust and adaptable to additions or changes in transaction processes without the risk of cross-state interferences .

You might also like