java 策略不同论点

java strategy different arguments

学习策略模式我想知道这是否适用于我的一部分代码。

所以假设有一个 class 叫做 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
        }
    }

}

如您所见,有一个名为 initializeOrder() 的方法,带有 if-else 语句,我认为它是策略模式的一个很好的候选者,以取代 if-else 语句。 但事实证明,如果我创建不同的策略,他们将需要不同的参数。

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

    }
}

正如您可能看到的那样,每个策略都有自己的多余参数。在这种情况下如何实施战略模式有什么想法吗?或者这可能根本不适用,也许还有其他模式?

请注意,这只是一个示例,我只是提供了 orderValueuser 参数作为例子。 在我的真实代码中可能会有更多的参数,但重点是每个策略肯定会有不同的参数来初始化订单。

您可以拥有一个包含必要内容的 UserOrder 对象,并将其作为参数传递

在您的情况下,它不会使用 InitializeOrderBasedOnProvidedValue

中的所有内容

我知道,它只是在解决你想知道的问题。

策略更像是选择算法来做不同的事情 - 想想搜索或排序。

如果这只是专注于避免 if 语句,那么策略模式在这里可能有点矫枉过正。不过,为了争论起见,这里有一个我认为可以实现你所要求的建议。

您可以考虑将传递不同参数的工作转移到每个 class 的构造函数中。 OrderInitializerStrategy 的 2 个实现 classes 不需要具有相同签名(相同参数)的构造函数。因此,您可以只传递该策略需要的每个构造函数。 initialize 方法可以不接受任何参数。

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
    }
}