Search code examples
javastrategy-pattern

java strategy different arguments


Learning strategy pattern I was wondering it this is applicable to one part of my code.

So let's say that there's a class called UserService

class UserService {

    ... some fields

    public void execute(String orderValue) {
        ... some business logic
        User user = ... // somehow received user here
        ... some more business logic

        // now i need to initialize an order
        Order order = initializeOrder(orderValue, user)

        ... business logic continues here
    }

    private Order initializeOrder(String orderValue, User user) {
        if (orderValue != null) {
            ... initialize order using String value
        } else {
            ... initialize order using user argument
        }
    }

}

As you can see there's a method called initializeOrder() with if-else statement and I thought it would be a good candidate for a strategy pattern in order to replace that if-else statement. But it turns out that if I create different strategies they will need different arguments.

interaface OrderInitializeStrategy {
    Order initialize(String orderValue, User user);
}

class InitializeOrderBasedOnProvidedValue implements OrderInitializeStrategy {
    public Order initialize(String orderValue, User user) {

        // user argument will never be used here, all I need is orderValue 

    }
}

class DefaultOrderInitializer implements OrderInitializeStrategy {
    public Order initialize(String orderValue, User user) {

        // need only user and probably there maybe more arguments, but orderValue will never be used

    }
}

As you probably may see each strategy has its own excess arguments. Any ideas how to implement a strategy pattern in this case? Or maybe this is not applicable here at all, maybe are there some other patterns?

Please note that this is just an example, and I just provided orderValue and user arguments just as an example. In my real code there may be some more argument, but the main point was that each strategy will definitely have different arguments in order to initialize an order.


Solution

  • If this is just focused on avoiding the if statement, then the strategy pattern might be overkill here. For the sake of argument though, here is a suggestion that I think achieves what you asked.

    You could consider moving the work of passing the different arguments into each class's constructor. It is not required that the 2 implementing classes of OrderInitializerStrategy have constructors with the same signatures (same arguments). Therefore, you could pass each constructor only what that strategy needs. The initialize method could then accept no arguments.

    interface OrderInitializeStrategy {
        Order initialize();
    }
    
    class InitializeOrderBasedOnProvidedValue implements OrderInitializeStrategy {
        private final String orderValue;
    
        public InitializeOrderBasedOnProvidedValue(String orderValue) {
            this.orderValue = orderValue;
        }
    
        @Override
        public Order initialize() {
            // user argument will never be used here, all I need is orderValue 
        }
    }
    
    class DefaultOrderInitializer implements OrderInitializeStrategy {
        private final User user;
    
        public DefaultOrderInitializer(User user) {
            this.user = user;
        }
    
        @Override
        public Order initialize() {
            // need only user and probably there maybe more arguments, but orderValue will never be used
        }
    }