如何避免需要用户代码了解和实例化策略模式中的具体策略

How to avoid need for User code knowing and instantiating concrete Strategy in Strategy Pattern

Strategy pattern 将上下文代码与其使用的策略(或算法或策略)分离。它比 Template Pattern 有优势,因为它支持动态行为更改并使用委托组合来实现它。下面就是这样的例子。

public class Context{
    private Policy policy;

    public void setPolicy(Policy policy){
        this.policy = policy;
    }

    public performTask(){
        policy.apply(); // delegate policy apply to separate class
        this.contextualWOrk();
    }
}

public interface Policy{
    void apply();
}

public class PolicyX{
     public void apply(){
         //Policy X implementation
     }
}

public class PolicyY{
     public void apply(){
         //Policy Y implementation
     }
}

现在代码使用上面的代码

public class User{
    public void init(Context context){
         context.setPolicy(new PolicyX());
         context.performTask();
    }
}

上面我们看到用户代码必须知道并向上下文提供具体的策略。我们可以使用像 Factory method pattern 这样的创建模式,但在这种情况下,用户代码仍然必须知道具体的工厂 class。这需要用户代码 实例化 并且 知道 这种具体实现的存在。

为了防止这种情况,一个简单的解决方案可以是使用一个静态方法,将输入作为字符串或枚举,并使用 'switch-case' 或多个 'if-else' 语句来决定实例化哪个 class 并提供对用户代码的实现。但这再次违反了 'OCP',因为添加新类型将需要修改代码。

如何在简单的应用程序中遵循这些原则(我不确定是否可以使用某些配置 Spring 和其他框架来解决此类问题)。

在简单应用中解决此问题的任何提示或关键点都会有所帮助。

第 318 页提到了策略模式的这个缺点。

Clients must be aware of different Strategies. The pattern has a potential drawback in that a client must understand how Strategies differ before it can select the appropriate one. Clients might be exposed to implementation issues. Therefore you should use the Strategy pattern only when the variation in behavior is relevant to clients.

正如您所注意到的,策略选择机制可以隐藏在其他代码层之后,或者移动到配置文件中;但仍然必须在某个地方进行基础选择。这只是选择应用模式时要注意的模式的一个缺点。