Bird
Raised Fist0

Design a Chess Game - Board, Pieces, Move Validation, Check Detection, Turn

LLDhardInterview freq: medium
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/4
Piece abstract class

Piece is an abstract class holding shared state like position and color, which interfaces cannot hold in Java.

🎯 Tests whether candidate understands abstract class is chosen over interface because Piece needs instance fields for position and color.
public abstract class Piece {
    protected Position position;
    protected Color color;
    public abstract boolean canMoveTo(Position newPos);
}
King concrete class

King extends Piece and implements specific move logic by overriding canMoveTo method.

🎯 Tests if candidate knows how to extend abstract class and override behavior without modifying base class, following Open/Closed Principle.
public class King extends Piece {
    @Override
    public boolean canMoveTo(Position newPos) {
        // King-specific move validation logic
        return true; // simplified
    }
}
Game singleton with composition

Game is a singleton class that composes Board and manages game state; composition means Board lifecycle is owned by Game.

🎯 Tests if candidate understands volatile singleton instance for thread-safe lazy init and composition lifecycle ownership.
public class Game {
    private static volatile Game instance;
    private Board board; // composition: Board lifecycle owned by Game
    private Color currentTurn;
    private Game() {
        board = new Board();
    }
    public static Game getInstance() {
        if (instance == null) {
            synchronized(Game.class) {
                if (instance == null) instance = new Game();
            }
        }
        return instance;
    }
    public synchronized void startGame() {
        // initialize game
    }
}
MoveValidator interface

MoveValidator is an interface defining move validation behavior, enabling different validation strategies without state.

🎯 Tests if candidate knows interface is used here to enforce Open/Closed Principle by allowing multiple implementations without changing clients.
public interface MoveValidator {
    boolean isValidMove(Move move);
}
📐
Class Diagram
Class Diagram
       +----------------+
       | <<Abstract>>   |
       | Piece          |
       |----------------|
       | -position: Pos |
       | -color: Color  |
       |----------------|
       | +canMoveTo(Pos):|
       |   boolean      |
       +----------------+
              │ extends
       +----------------+
       | King           |
       |----------------|
       |                |
       | +canMoveTo(Pos):|
       |   boolean      |
       +----------------+
       
       +----------------+
       | <<Singleton>>  |
       | Game           |
       |----------------|
       | -board: Board  |◆ composition
       | -currentTurn   |
       |----------------|
       | +startGame():  |
       |   void [sync]  |
       +----------------+
       
       +----------------+
       | <<Interface>>  |
       | MoveValidator  |
       |----------------|
       | +isValidMove(  |
       |   Move):boolean|
       +----------------+

This class diagram illustrates key Java-specific design decisions for a Chess game. Piece is an abstract class because it holds shared mutable state like position and color, which interfaces cannot hold in Java. King extends Piece to provide concrete move logic, demonstrating inheritance and Open/Closed Principle by extending behavior without modifying base class. Game is a thread-safe singleton using volatile and double-checked locking to ensure safe lazy initialization, and it composes Board, owning its lifecycle. MoveValidator is an interface representing the strategy pattern for move validation, enabling extensibility without changing existing code. Synchronized methods in Game ensure atomic state changes during game start. These decisions enforce SOLID principles and correct Java concurrency mechanisms.

Primary Focus

✓ Abstract class state vs interface behavior + Composition lifecycle + Interface realization + Synchronized method usage

Practice

(1/5)
1. In a Music Streaming Library design, a Playlist class has a private constructor and a static synchronized getInstance() method that returns the single instance. Which design pattern is applied here and why is it the correct choice?
easy
A. Factory pattern, because it controls object creation centrally.
B. Builder pattern, to construct complex Playlist objects step-by-step.
C. Prototype pattern, to clone existing Playlist instances efficiently.
D. Singleton pattern, to ensure only one Playlist instance manages the playback queue globally.

Solution

  1. Step 1: Identify the pattern from private constructor and static synchronized getInstance()

    This is the Singleton pattern, which restricts instantiation to one object and provides a global access point.
  2. Step 2: Why Singleton fits Playlist playback queue management

    Since the playback queue must be globally consistent and unique per user session, Singleton ensures only one instance manages it, avoiding conflicting states.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Private constructor + synchronized getInstance() -> Singleton pattern [check]
Hint: Private constructor + static getInstance() = Singleton [check]
Common Mistakes:
2. In designing the Workflow Engine, should the Condition component be an abstract class or an interface, and why?
easy
A. Interface, because Conditions only define a contract for evaluation without shared state, allowing multiple implementations.
B. Abstract class, because Java interfaces cannot have default methods for condition evaluation logic.
C. Abstract class, because Conditions share common state and behavior that subclasses must inherit.
D. Interface, because it allows Conditions to hold mutable state safely across threads.

Solution

  1. Step 1: Analyze Condition's role

    Conditions define evaluation logic without requiring shared state; they represent a contract for boolean checks.
  2. Step 2: Interface vs Abstract class

    Interface suits stateless behavior contracts and allows multiple inheritance; abstract class implies shared state, which is not needed and limits flexibility.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Condition defines behavior only -> interface [check]
Hint: Stateless behavior contracts -> interface, not abstract class [check]
Common Mistakes:
3. In designing a Vehicle abstraction, should it be an abstract class or an interface if it needs to hold common state like speed and fuelLevel? Why?
easy
A. Use an interface, because interfaces can hold state and provide default implementations.
B. Use an abstract class, because it can hold instance variables and provide shared behavior.
C. Use an interface, because it enforces implementation without sharing any code or state.
D. Use an abstract class, because interfaces cannot declare methods.

Solution

  1. Step 1: Analyze state and behavior requirements

    Since Vehicle needs to hold common state like speed and fuelLevel, it requires instance variables.
  2. Step 2: Choose abstraction supporting state

    Abstract classes can have instance variables and shared method implementations, whereas interfaces cannot hold instance state (only constants and default methods without state).
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    State requires instance variables -> abstract class [check]
Hint: State needs fields -> abstract class; interfaces only declare behavior [check]
Common Mistakes:
4. You need to add support for ElectricCar that requires ChargingSpot compatibility in the current parking system. What is the minimum change to the design to support this without modifying existing classes?
hard
A. Modify Vehicle class to add a boolean needsCharging and update parking logic to check this flag.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP accordingly.
C. Create a new ElectricParkingLot subclass that handles electric cars and charging spots separately.
D. Add a ChargingSpot field to Vehicle and modify all parking methods to handle it.

Solution

  1. Step 1: Identify extensibility requirements

    ElectricCar and ChargingSpot are new types requiring compatibility mapping without changing existing classes.
  2. Step 2: Apply minimal invasive change

    Adding new enum values and subclass plus updating compatibility map extends functionality without modifying existing class code, preserving OCP.
  3. Step 3: Avoid violating OCP

    Options B, C, and D modify existing classes or create parallel hierarchies, increasing complexity and violating OCP.
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Extend enums and map, subclass ElectricCar -> minimal change [check]
Hint: Extend enums and map, subclass new type -> minimal change [check]
Common Mistakes:
5. ElectricCar requires ChargingSpots in the parking lot system. What is the minimum change to support this without modifying existing classes?
hard
A. Add a boolean isElectric flag to Vehicle and Spot classes and handle compatibility internally.
B. Modify Vehicle and Spot classes to add electric-specific fields and logic directly.
C. Create a new ElectricParkingLot subclass handling electric vehicles and spots separately.
D. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    To comply with OCP and avoid class explosion, new types should be added via enums and new subclasses without changing existing code.
  2. Step 2: Explain why Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally. fits minimal change

    Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally. adds new enum values and creates a new ElectricCar subclass, updating compatibility externally, preserving existing classes unchanged. Options B, C, and D modify existing classes or create subclasses that duplicate logic, violating OCP or SRP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    New enums + subclass + external compatibility update -> minimal change [check]
Hint: Add enums + subclass + external map update -> no existing class changes [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard