javaoopdesign-patternslazy-initializationstate-pattern

Does it makes sense to use state pattern with virtual proxies?


class HeavyweightObjcet
{
    public void operate() {
        System.out.println("Operating...");
    }
}

class LazyInitializer
{
    HeavyweightObjcet objcet;

    public void operate()
    {
        if (objcet == null)
            objcet = new HeavyweightObjcet();
        objcet.operate();
    }
}

Here I'm making a virtual proxy for a heavyweight object. Each time before calling HeavyweightObject::operate, the program checks first whether the object is null or not. This part is checked once and only once through the entire lifetime of the object.

A possible improvement maybe using the state pattern like this:

class HeavyweightObjcet
{
    public void operate() {
        System.out.println("Operating...");
    }
}

class LazyInitializer
{
    HeavyweightObjcet objcet;
    State state = new UninitializedState(this);

    public void operate()
    {
        state.operate();
    }
}

abstract class State
{
    LazyInitializer initializer;

    public State(LazyInitializer initializer)
    {
        this.initializer = initializer;
    }

    abstract void operate();
}

class UninitializedState extends State
{
    public UninitializedState(LazyInitializer initializer) {
        super(initializer);
    }

    @Override
    public void operate() {
        initializer.objcet = new HeavyweightObjcet();
        initializer.state = new InitializedState(initializer);
        initializer.operate();
    }
}

class InitializedState extends State
{
    public InitializedState(LazyInitializer initializer) {
        super(initializer);
    }

    @Override
    public void operate() {
        initializer.objcet.operate();
    }
}

Does this solution make sense?

Is there any possible improvement to the code?

Are there any examples to something like this that's done before?

Is it an unnecessary complication or does it worth it or does it depend on the situation?

Does it make the code faster? I mean, the extra function calls may be slower than just a simple conditional.


Solution

  • Is it an unnecessary complication or does it worth it or does it depend on the situation?

    While it is completely fine to have only 2 states when using the State Pattern, it is most definitely an overkill in this particular case for the following reasons :

    1. There will only ever be one state transition from UninitializedState -> InitailizedState. Once HeavyWeightObjcet has been initialized, you are most definitely not going to alternate between transitioning from InitializedState -> UninitializedState or vice-versa
    2. There is a reason why we have design principles such as YAGNI (You aren't gonna need it) and KISS (Keep it simple, stupid). Don't introduce complexities in the first iteration of the code. Let the design evolve as a part of continuous refactoring.
    3. While the above example looks good on paper, the real world is a different ballgame altogether. There are more important problems to address in the code in the real world. (For example, is the operate method thread-safe?)

    Does it make the code faster? I mean, the extra function calls may be slower than just a simple conditional.

    This is too small an area to be worrying about when it comes to performance Read : micro-optimization

    Last but not the least, the State Pattern allows us to adhere to the Open-Closed principle.. As the example stands, there is no convincing reason for the operate method to change as far as initialization of the HeavyWeightObject is concerned. Moreover, the initialization code should be in the constructor rather than the operate method in the first place.