[23种设计模式][行为型]03.策略模式

115 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第N天,点击查看活动详情

1.策略模式(Strategy):

策略模式(Strategy)中体现了两个非常基本的面向对象设计原则

  • 封装变化的概念
  • 编程中使用接口,而不是对接口实现,面向接口的编程

2.策略模式的定义:

  • 定义一组算法,将每个算法都封装起来,并且使它们之间可以互换
  • 策略模式使这些算法在客户端调用它们的时候能够互不影响地变化

3.策略模式的意义:

  • 策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是弱连接的关系。
  • 弱连接的特性使软件具有更强的可扩展性,易于维护;更重要的是,它大大提高了软件的可重用性。

4.策略模式的组成:

  • 抽象策略角色:策略类,通常由一个接口或者抽象类实现。
  • 具体策略角色:包装了相关的算法和行为。
  • 环境角色:持有一个策略类的引用,最终给客户端调用。

5.策略模式的实现:

  • 策略模式的用意是针对一组算法,将每一个算法封装到具有共同的独立的类中,从而使得它们可以相互替换。
  • 策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。
  • 环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来,算法的修改都不会影响环境和客户端。

6.策略模式的编写步骤:

  1. 对策略对象定义一个公共接口。
  2. 编写策略类,该类实现了上面的公共接口。
  3. 在使用策略对象的类中保存一个对策略对象的引用。
  4. 在使用策略对象的类中,实现对策略对象的set和get。(注入)或者使用构造方法完成赋值。

7.策略模式的缺点:

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 造成很多的策略类。

8.解决方案:

  • 采用工厂方法

9.策略模式UML图:

Image.png

10.策略模式序列图:

Image.png

11.代码示例:

Image.png

客户端:

public class Client {
    public static void main(String[] args) {
        Context context = new Context();
        context.add(1);
        context.add(9);
        context.add(-3);
        context.add(-1);
        
        context.setStrategy(new QuickSortStrategy());
        context.sort();
        context.display();

        System.out.println("---------------");

        context.setStrategy(new BubbleSortStrategy());
        context.sort();
        context.display();
    }
}

抽象策略:

public interface Strategy {
    void sort(List<Integer> list);
}

具体策略2:

public class QuickSortStrategy implements Strategy {

    @Override
    public void sort(List<Integer> list) {
        Collections.sort(list);

        System.out.println("Quick Sort");
    }
}

具体策略1:

public class BubbleSortStrategy implements Strategy {
    @Override
    public void sort(List<Integer> list) {

        boolean flag = false;
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.size() - 1 - i; j++) {
                if (list.get(j) > list.get(j + 1)) {
                    int temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, temp);

                    flag = true;
                }
            }

            if (!flag) {
                break;
            }
        }

        System.out.println("Bubble Sort");
    }
}

客户端:

public class Context {

    private List<Integer> list = new ArrayList<>();

    private Strategy strategy;

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

    public void sort() {
        this.strategy.sort(list);
    }

    public void add(int i) {
        list.add(i);
    }

    public void display() {
        for (int i : list) {
            System.out.println(i);
        }
    }
}