WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Design Patterns · Advanced · question 46 of 100

Describe how you can combine the State pattern with the Flyweight pattern to optimize memory usage in a large state machine.?

📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

The State pattern is a behavioral design pattern that allows an object to alter its behavior when its internal state changes. The Flyweight pattern, on the other hand, is a structural design pattern that allows sharing objects to support large numbers of fine-grained objects with a minimal memory footprint.

When working with a large state machine using the State pattern, we can take advantage of the Flyweight pattern to optimize memory usage. We can create a shared pool of State objects that can be reused by different contexts. This shared pool of State objects is known as the flyweight objects and can drastically reduce the memory footprint of the state machine.

To implement this optimization, we can update the Context class to use a Flyweight factory instead of creating new State objects every time its state changes. The Flyweight factory will maintain a pool of flyweight objects and will return an existing object if available, or create a new object if necessary. Each flyweight object will contain only the state-specific data, while the state machine’s Context class will store the non-state-specific data.

Here is an example implementation in Java:

First, we define the State interface, which contains the common behavior of all states.

public interface State {
    void performAction(Context context);
}

Next, we implement the ConcreteStateA and ConcreteStateB classes that represent specific states.

public class ConcreteStateA implements State {
    @Override
    public void performAction(Context context) {
        // perform action for state A
        // update state if necessary
        context.setState(/** new state **/);
    }
}

public class ConcreteStateB implements State {
    @Override
    public void performAction(Context context) {
        // perform action for state B
        // update state if necessary
        context.setState(/** new state **/);
    }
}

We then update the Context class to use the Flyweight factory to manage states.

public class Context {
    private State currentState;
    private FlyweightFactory flyweightFactory;

    public Context() {
        flyweightFactory = new FlyweightFactory();
        currentState = flyweightFactory.getState(/** initial state **/);
    }

    public void performAction() {
        currentState.performAction(this);
    }

    public void setState(State state) {
        currentState = flyweightFactory.getState(state);
    }
}

Finally, we implement the FlyweightFactory class to create and manage flyweight objects.

public class FlyweightFactory {
    private Map<State, State> flyweights = new HashMap<>();

    public State getState(State state) {
        if (!flyweights.containsKey(state)) {
            flyweights.put(state, state);
        }
        return flyweights.get(state);
    }
}

By using the Flyweight pattern in conjunction with the State pattern, we can reduce the memory footprint of a large state machine and optimize its performance.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Design Patterns interview — then scores it.
📞 Practice Design Patterns — free 15 min
📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

All 100 Design Patterns questions · All topics