设计模式-策略模式

文章目录

一、前言

在软件设计中,我们经常会面临需要根据不同情况选择不同算法或方法的问题。这些情况可能是基于不同的输入、不同的需求或不同的环境。策略模式(Strategy Pattern)是一种行为型设计模式,它能够让我们以一种优雅的方式在运行时选择算法,从而提高代码的灵活性和可维护性。

二、知识点构成

1、策略模式介绍

策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。

2、理解策略模式

策略模式的核心思想是将不同的算法封装成独立的类,并且使这些类可以互相替换。这样,我们可以在运行时根据需要动态地切换算法,而不需要修改调用算法的代码。策略模式主要由三个角色组成:

2.1、策略接口(Strategy Interface)

定义了具体策略类(算法类)必须实现的方法,确保所有策略类都具有相同的行为约定。

java 复制代码
interface SortingStrategy {
    void sort(int[] array);
}

2.2、具体策略类(Concrete Strategies)

实现了策略接口,封装了具体的算法逻辑。

java 复制代码
class BubbleSort implements SortingStrategy {
    @Override
    public void sort(int[] array) {
        // 实现冒泡排序算法
    }
}

class QuickSort implements SortingStrategy {
    @Override
    public void sort(int[] array) {
        // 实现快速排序算法
    }
}

2.3、上下文类(Context)

持有一个策略对象,并在运行时根据需要调用具体的策略,将算法的选择和使用与客户端代码解耦。

java 复制代码
class Sorter {
    private SortingStrategy strategy;

    public void setStrategy(SortingStrategy strategy) {
        this.strategy = strategy;
    }

    public void performSort(int[] array) {
        strategy.sort(array);
    }
}

2.4、客户端使用

java 复制代码
public class Main {
    public static void main(String[] args) {
        int[] data = {5, 2, 8, 1, 3};

        Sorter sorter = new Sorter();
        sorter.setStrategy(new BubbleSort());
        sorter.performSort(data);

        // 或者切换到另一个策略
        sorter.setStrategy(new QuickSort());
        sorter.performSort(data);
    }
}

3、优点与应用

策略模式的优点在于它能够将不同算法的实现与调用代码分离,使得代码更易于理解、扩展和维护。它适用于以下场景:

  • 当有多种算法可以选择时,通过策略模式可以避免使用复杂的条件语句。
  • 当一个类有多个行为变体,而这些变体经常需要在运行时切换时,策略模式是一个好的选择。
  • 当需要在不同的上下文中使用不同的算法时,策略模式可以让算法与上下文独立变化,互不影响。

4、策略模式的优化

当你新增一个算法策略子类时,客户端的代码需要进行修改,这违反了开闭原则。开闭原则要求软件实体(类、模块、函数等)应该是可扩展的,而不需要修改已有的代码。但是在实际情况中,新增策略可能需要客户端代码进行相应的调整,因为你需要告诉上下文类应该使用哪个新策略。

假如我们新增一个归并排序算法:

java 复制代码
class MergeSort implements SortingStrategy {
    @Override
    public void sort(int[] array) {
        // 实现归并排序算法
    }
}

在我们的客户端类要想使用归并排序算法的话就需要进行修改了;

java 复制代码
public class Main {
    public static void main(String[] args) {
        int[] data = {5, 2, 8, 1, 3};

        Sorter sorter = new Sorter();
        sorter.setStrategy(new BubbleSort());
        sorter.performSort(data);

        // 或者切换到另一个策略
        sorter.setStrategy(new QuickSort());
        sorter.performSort(data);

		// 切换到归并排序
        sorter.setStrategy(new MergeSort());
        sorter.performSort(data);
    }
}

4.1、反射+配置文件优化策略模式

创建一个配置文件,用于存储所支持的不同排序策略的类名。这个配置文件可以是 XML、JSON 或者简单的文本文件,取决于你的喜好和项目的需要。

yml 复制代码
bubbleSort=your.package.BubbleSort
quickSort=your.package.QuickSort
mergeSort=your.package.MergeSort

修改上下文类:

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

class Sorter {
    private SortingStrategy strategy;

    public Sorter() {
        loadConfiguration();
    }

    public void performSort(int[] array) {
        strategy.sort(array);
    }

    private void loadConfiguration() {
        Properties properties = new Properties();
        try (InputStream inputStream = getClass().getResourceAsStream("strategies.properties")) {
            properties.load(inputStream);
            String strategyClassName = properties.getProperty("selectedStrategy");
            strategy = createStrategyInstance(strategyClassName);
        } catch (IOException | ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
            // 处理异常,设置默认策略
        }
    }

    private SortingStrategy createStrategyInstance(String className)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> strategyClass = Class.forName(className);
        return (SortingStrategy) strategyClass.newInstance();
    }
}

通过使用反射和配置文件,你可以实现一种更加灵活的策略模式,避免了新增策略时需要修改客户端代码的问题。至于它要选择哪种策略,我们可以设置成一个变量,通过前端进行传入,让用户自己选择想要的策略,这样如果新增一个策略算法的话,只需要新增一个策略子类实现策略接口重写算法,然后在配置文件中新增一个对应关系即可;

三、总结

策略模式是一种强大的工具,可以帮助我们在代码中处理不同算法的选择问题。通过将算法封装成独立的策略类,我们可以轻松地在运行时切换和扩展这些算法,从而实现更加灵活和可维护的代码。无论是在排序算法还是其他需要动态选择不同实现的情景中,策略模式都是一个值得考虑的设计方案。

相关推荐
澄澈i23 分钟前
设计模式学习[9]---模板方法模式
c++·学习·设计模式·模板方法模式
zzzhpzhpzzz31 分钟前
设计模式——解释器模式
算法·设计模式·解释器模式
DBWYX1 小时前
GoF设计模式——结构型设计模式分析与应用
设计模式
repinkply2 小时前
装饰模式(Decorator)模式:装饰模式/包装模式,结构模式
设计模式·c++设计模式·装饰器模式·装饰模式·包装模式
霁月风3 小时前
设计模式——装饰器模式
c++·设计模式·装饰器模式
夏旭泽3 小时前
设计模式-原型模式
设计模式·原型模式
zzzhpzhpzzz4 小时前
设计模式——观察者模式
算法·观察者模式·设计模式
小白不太白9506 小时前
设计模式之 迭代器模式
java·设计模式·迭代器模式
闲人一枚(学习中)6 小时前
设计模式-创建型-单例模式
java·单例模式·设计模式
水宝的滚动歌词6 小时前
设计模式之单例模式
单例模式·设计模式