Bird
Raised Fist0

Design a Plugin Architecture - Plugin Interface, Registry, Loader, Dependency

LLDhardInterview freq: medium
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/5
Plugin Interface

Plugin defines the contract with getName() and execute() methods without state.

🎯 Tests understanding that interfaces in Java cannot hold instance state and define behavior only.
public interface Plugin {
    String getName();
    void execute();
}
AbstractPlugin Abstract Class

AbstractPlugin implements Plugin and holds shared state 'name' with synchronized getName().

🎯 Tests why abstract class is used over interface due to shared state and synchronized method for thread safety.
public abstract class AbstractPlugin implements Plugin {
    private final String name;
    public AbstractPlugin(String name) {
        this.name = name;
    }
    public synchronized String getName() {
        return name;
    }
}
PluginLoader Composition

PluginLoader composes PluginRegistry (composition) and synchronizes load() to atomically load plugins.

🎯 Tests composition lifecycle ownership and synchronized load() to prevent concurrent load conflicts.
public class PluginLoader {
    private final PluginRegistry registry = new PluginRegistry();
    public synchronized Plugin load(String pluginName) throws PluginLoadException {
        // loading logic
        return null;
    }
}
PluginRegistry Thread Safety

PluginRegistry holds plugins map and synchronizes register() to ensure thread-safe plugin registration.

🎯 Tests synchronized register() method to avoid race conditions on plugins map mutation.
public class PluginRegistry {
    private final Map<String, Plugin> plugins = new HashMap<>();
    public synchronized void register(Plugin plugin) {
        plugins.put(plugin.getName(), plugin);
    }
    public Plugin get(String name) {
        return plugins.get(name);
    }
}
PluginLoadException Usage

PluginLoadException is a checked exception used to signal plugin loading failures explicitly.

🎯 Tests understanding of checked exceptions in Java for explicit error handling in plugin loading.
public class PluginLoadException extends Exception {
    public PluginLoadException(String message) {
        super(message);
    }
}
📐
Class Diagram
Class Diagram
       +----------------+
       | <<Interface>>  |
       |    Plugin      |
       +----------------+
       | +getName():Str |
       | +execute():void|
       +----------------+
              ─ ─ ─►
       +----------------+
       | <<Abstract>>   |
       | AbstractPlugin |
       +----------------+
       | -name: String  |
       +----------------+
       | +getName():Str [sync]|
       | +execute():void      |
       +----------------+
              │ extends
       +----------------+
       | PluginLoader   |
       +----------------+
       | -reg: PluginReg ◆|
       +----------------+
       | +load(String):Plg [sync]|
       +----------------+
              ──► association
       +----------------+
       | PluginRegistry |
       +----------------+
       | -plugins: Map  |
       +----------------+
       | +register(Plg):void [sync]|
       | +get(String):Plg          |
       +----------------+
              ──►
       +---------------------+
       | PluginLoadException |
       +---------------------+
       | +PluginLoadExcep(String)|
       +---------------------+

This diagram illustrates a plugin architecture using a Java interface Plugin to define behavior without state, enforcing the Open-Closed Principle. AbstractPlugin is an abstract class that implements Plugin and holds shared state 'name' with a synchronized getter, demonstrating why abstract classes are preferred over interfaces when state is needed. PluginLoader composes PluginRegistry, owning its lifecycle, and synchronizes load() to ensure thread-safe plugin loading, enforcing Single Responsibility and Liskov Substitution principles. PluginRegistry synchronizes register() to prevent concurrent modification bugs on its internal map, showing precise concurrency control with synchronized methods. PluginLoadException is a checked exception used to explicitly signal loading errors, demonstrating Java's exception handling best practices.

Primary Focus

✓ Abstract class vs Interface + Composition lifecycle + Exception usage + Realization

Practice

(1/5)
1. In a Java system, a Subject class maintains a list of Observer interfaces and notifies them on state changes. Which design pattern is this an example of, and why is it the correct choice for decoupling components?
easy
A. Observer pattern, because it allows subjects to notify multiple observers without knowing their concrete classes.
B. Mediator pattern, because it centralizes communication between objects to reduce dependencies.
C. Decorator pattern, because it dynamically adds responsibilities to objects without affecting others.
D. Strategy pattern, because it encapsulates interchangeable algorithms for flexible behavior.

Solution

  1. Step 1: Identify the pattern based on roles

    The Subject maintains a list of Observer interfaces and notifies them on state changes, which matches the Observer pattern's intent to decouple the subject from its observers.
  2. Step 2: Eliminate other patterns

    Mediator centralizes communication but does not involve a subject notifying observers; Decorator adds behavior dynamically but does not handle notification; Strategy encapsulates algorithms but does not manage dependent objects.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Subject notifying observers without knowing concrete classes -> Observer pattern [check]
Hint: Subject notifies observers, decoupling sender and receivers [check]
Common Mistakes:
2. The framework currently applies a FeeStrategy interface for scoring rules. To add a WeekendBonusStrategy that modifies scoring only on weekends, what is the minimum change required to comply with SOLID principles?
medium
A. Modify the existing FeeStrategy implementations to check for weekends internally.
B. Create a combined strategy class that inherits from all existing strategies and adds weekend logic.
C. Add a boolean flag isWeekend to the base class and branch logic accordingly.
D. Add a new WeekendBonusStrategy class implementing FeeStrategy and configure it without changing existing classes.

Solution

  1. Step 1: Identify applicable SOLID principle

    The Open-Closed Principle (OCP) requires that existing classes remain unchanged when adding new functionality.
  2. Step 2: Evaluate options against OCP

    Add a new WeekendBonusStrategy class implementing FeeStrategy and configure it without changing existing classes. adds a new class implementing the interface, extending behavior without modifying existing code, thus respecting OCP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    New class implements interface -> no existing class modified -> OCP [check]
Hint: Add new class, don't modify existing -> OCP compliance [check]
Common Mistakes:
3. In the seat booking process, if the bookSeat() method is not synchronized, which exact sequence of events between Thread 1 and Thread 2 causes double-booking of the same seat?
medium
A. Thread 1 checks seat availability -> true, context switch before booking; Thread 2 checks availability -> true, both book seat concurrently.
B. Thread 1 reads seat as available, Thread 2 reads seat as occupied, both proceed to book.
C. Thread 1 locks seat, Thread 2 waits and retries after release, no double-booking occurs.
D. Thread 1 and Thread 2 both fail to read seat status due to cache inconsistency.

Solution

  1. Step 1: Trace Thread 1's check-then-act gap

    Thread 1 reads seat as available but is preempted before marking it booked.
  2. Step 2: Thread 2 also reads seat as available and proceeds to book, causing double-booking.

    Without synchronization, both threads act on stale availability state.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act gap without lock -> double-booking [check]
Hint: Check availability -> context switch -> both book [check]
Common Mistakes:
4. To add a WeekendFeeStrategy for bounty fees in the current Stack Overflow design, which minimal change respects the Open/Closed Principle (OCP)?
medium
A. Add a boolean flag isWeekend to Bounty and handle fees internally
B. Modify the existing BountyFeeCalculator class to add weekend logic with if-else
C. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without changing existing classes
D. Create a subclass WeekendBountyFeeCalculator extending BountyFeeCalculator and override fee calculation

Solution

  1. Step 1: Understand OCP in fee strategy context

    OCP requires adding new behavior without modifying existing code.
  2. Step 2: Evaluate options for minimal change and OCP compliance

    Add a boolean flag isWeekend to Bounty and handle fees internally adds a flag and internal logic, modifying existing class behavior, violating OCP. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without changing existing classes adds a new strategy class without modifying existing classes, respecting OCP. Modify the existing BountyFeeCalculator class to add weekend logic with if-else modifies existing class, violating OCP. Create a subclass WeekendBountyFeeCalculator extending BountyFeeCalculator and override fee calculation creates subclass but may cause complexity and violates DIP if clients depend on concrete subclass.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New strategy class + injection -> OCP respected [check]
Hint: New strategy class -> OCP respected, no existing class change [check]
Common Mistakes:
5. You want to add a WeekendFeeStrategy to calculate parking fees differently on weekends using the current Iterator-based design. Which minimal change respects the Open-Closed Principle (OCP)?
medium
A. Add a boolean flag isWeekend to the FeeStrategy interface and implement conditional logic in all subclasses.
B. Modify the existing FeeStrategy class to add weekend logic with an if-else condition.
C. Create a new WeekendFeeStrategy class implementing FeeStrategy and update the client code to use it when appropriate.
D. Combine all fee strategies into a single class with multiple methods and switch logic inside the iterator.

Solution

  1. Step 1: Understand OCP requirements

    OCP requires software entities to be open for extension but closed for modification.
  2. Step 2: Evaluate options

    Modify the existing FeeStrategy class to add weekend logic with an if-else condition. modifies existing class, violating OCP. Create a new WeekendFeeStrategy class implementing FeeStrategy and update the client code to use it when appropriate. adds a new class but requires client code modification, which may violate DIP. Add a boolean flag isWeekend to the FeeStrategy interface and implement conditional logic in all subclasses. extends interface with a flag, allowing existing implementations to adapt without changing their core logic. Combine all fee strategies into a single class with multiple methods and switch logic inside the iterator. centralizes logic, violating SRP and OCP.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Extending interface with flag allows extension without modifying existing classes [check]
Hint: OCP: extend behavior without modifying existing classes [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