策略模式(Strategy Pattern)

132 阅读4分钟

策略模式(Strategy Pattern)

1.定义

策略模式(Strategy Pattern)是一种行为设计模式,它使你能在运行时改变对象的行为。在策略模式中,一个类的行为或其算法可以在其运行时更改。这种类型的设计模式属于行为模式。

策略模式的主要优点是:

  1. 算法可以自由切换:策略模式使得算法可以独立于使用它的客户端变化。
  2. 简化单元测试:策略模式使得每一个算法都有自己的类,这样我们可以通过自己的接口单独测试每一个算法。
  3. 开闭原则:策略模式对扩展开放,对修改封闭。

策略模式的缺点是:

  1. 客户端必须知道不同策略的存在:这使得客户端可以自行决定使用哪一个策略,这可能导致客户端代码变得复杂。
  2. 增加系统复杂性:由于策略模式将算法的使用与算法的实现分离,系统中会增加许多策略类。当策略过多时,可能会导致系统变得难以维护。

策略模式通常适用于以下场景:

  1. 许多相关的类仅仅是行为有异。
  2. 需要使用一个算法的不同变体。
  3. 算法使用客户不应该知道的数据。
  4. 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的策略类中替换这些条件语句。

2.实现

策略模式的实现主要包括以下步骤:

  1. 定义策略接口:首先,需要创建一个策略接口,该接口定义了一个或多个方法,这些方法会在具体的策略类中被实现。这些方法代表了某种行为或算法。
  2. 创建策略类:然后,创建多个实现了策略接口的类,每个类代表一种具体的策略或算法。这些类应该实现接口中定义的方法,并在方法内部提供具体的算法实现。
  3. 创建上下文类:上下文类(或称为策略使用者)是一个持有策略接口的引用,并调用策略接口中定义的方法的类。上下文类不需要知道它所使用的具体策略类的类型,它只需要知道策略接口。
  4. 在客户端代码中使用策略模式:客户端代码创建上下文类的一个实例,并通过构造函数或其他方法将所需策略的一个实例传递给上下文类。然后,客户端代码可以调用上下文类的方法来执行策略。

下面使用策略模式实现日志记录级别的改变:

1.UML类图:

image-20240324171501293.png

2.代码实现

要使用策略模式实现日志记录级别的改变,首先需要定义一个日志策略接口,然后为每种日志级别创建相应的策略实现类。接着,创建一个上下文类来管理这些策略,并在客户端代码中根据需要切换日志级别。

以下是一个简单的Java示例:

  1. 定义日志策略接口
public interface LoggingStrategy {  
    void log(String message);  
}
  1. 创建具体的日志策略类
public class DebugLoggingStrategy implements LoggingStrategy {  
    @Override  
    public void log(String message) {  
        System.out.println("[DEBUG] " + message);  
    }  
}  
  
public class InfoLoggingStrategy implements LoggingStrategy {  
    @Override  
    public void log(String message) {  
        System.out.println("[INFO] " + message);  
    }  
}  
  
public class WarningLoggingStrategy implements LoggingStrategy {  
    @Override  
    public void log(String message) {  
        System.out.println("[WARNING] " + message);  
    }  
}  
  
// 还可以添加其他日志级别,比如ERROR、FATAL等
  1. 创建上下文类
public class LoggingContext {  
    private LoggingStrategy loggingStrategy;  
  
    public LoggingContext(LoggingStrategy loggingStrategy) {  
        this.loggingStrategy = loggingStrategy;  
    }  
  
    public void setLoggingStrategy(LoggingStrategy loggingStrategy) {  
        this.loggingStrategy = loggingStrategy;  
    }  
  
    public void log(String message) {  
        loggingStrategy.log(message);  
    }  
}
  1. 在客户端代码中使用策略模式
public class Client {  
    public static void main(String[] args) {  
        LoggingContext loggingContext = new LoggingContext(new DebugLoggingStrategy()); // 初始设置为DEBUG级别  
          
        loggingContext.log("This is a debug message."); // 输出: [DEBUG] This is a debug message.  
  
        // 改变日志级别为INFO  
        loggingContext.setLoggingStrategy(new InfoLoggingStrategy());  
        loggingContext.log("This is an info message."); // 输出: [INFO] This is an info message.  
  
        // 可以根据需要继续切换日志级别  
        // loggingContext.setLoggingStrategy(new WarningLoggingStrategy());  
        // loggingContext.log("This is a warning message.");  
    }  
}

在这个例子中,LoggingContext 类管理了日志策略,客户端代码可以根据需要设置不同的日志策略。通过调用 setLoggingStrategy 方法,可以很容易地改变当前的日志级别。每次调用 log 方法时,LoggingContext 都会委托给当前设置的日志策略对象来执行实际的日志记录操作。

这种设计使得日志级别的改变变得非常灵活,客户端代码不需要关心具体的日志实现细节,只需要通过更改策略对象即可实现日志级别的动态切换。