19. 23种经典设计模式-33-策略模式

1. 策略模式(Strategy Pattern)

Define a family of algorithms, encapsulate eache one, and make them interchangeable. (定义一组算法, 将每个算法都封装起来,并使它们之间可以相互替换)

策略模式是一种非常简单的模式,核心就是面向接口编程. 只是粒度更小,将每种算法都单独成一个策略类. 策略模式有点儿类似于java8的函数式接口,可以将函数当做参数传递.

1.1 核心思想

  • 将算法(可变部分)抽处理单独成一个策略类, 使不同的算法可以自由切换
  • 策略模式其实就是面向接口编程的一种体现,只是将算法封装成了一个独立的类而已.
  • 策略模式体现了几个设计原则:
    • 把易变化的代码抽离出来,单独成类
    • 针对接口编程,而不是针对具体类编程.(策略接口)
    • 多用组合/聚合, 少用继承

1.2 策略模式-类图

  • Strategy: 抽象策略角色. 定义算法抽象方法. 通常一个策略接口中只定义一个算法
  • ConcreteStragy: 具体策略角色. 实现算法逻辑
  • Context: 封装角色, 起承上启下左右. 屏蔽高层模块儿对策略,算法的直接访问,封装可能的变化.

1.3 策略模式-优缺点

  • 优点:
    • 算法可以自由切换
    • 避免多重条件判断
    • 扩展性好: 新增算法实现时,新增一个策略即可
  • 缺点:
    • 策略类数量增多. 通常策略类遵守轻量化原则,一个策略便是一个类,因此会导致类的数量激增.
    • 所有策略类都需要向外暴露. 上层模块儿必须清晰知道每个策略类的特性,然后自行选择使用的策略类.
    • 违背迪米特法则

1.4 策略模式-适用场景

  • 多个类只有在算法或行为上稍有不同的场景
  • 算法需要自由切换的场景
  • 需要屏蔽算法规则实现细节的场景
  • jdk中集合的Compare方法便是一种策略模式

2. 策略模式-应用示例

策略模式主要是用来抽象算法的,那么我们就来模拟一个算法的例子. 我们指定排序算法有很多种,简单排序,快速排序,冒泡排序等, 我们将每种排序方式抽象为策略

2.1 类图

2.2 排序策略抽象接口-ISortStrategy

只定义一个抽象方法sort()

public interface ISortStrategy {
    void sort();
}

2.3 简单排序-SimpleSort

算法实现并不是本篇博客的重点,因此直接输出一条语句即可

public class SimpleSort implements ISortStrategy {
    @Override
    public void sort() {
        System.out.println("使用简单排序进行排序...");
    }
}

2.4 冒泡排序-BubbleSort

算法实现并不是本篇博客的重点,因此直接输出一条语句即可

public class BubbleSort implements ISortStrategy {
    @Override
    public void sort() {
        System.out.println("使用冒泡排序进行排序...");
    }
}

2.5 快速排序-QuickSort

算法实现并不是本篇博客的重点,因此直接输出一条语句即可

public class QuickSort implements ISortStrategy {
    @Override
    public void sort() {
        System.out.println("使用快速排序进行排序...");
    }
}

2.6 排序上下文-SortContext

  • 此类的存在,让策略模式有点儿类似于java8的函数式接口,可以将方法当做参数传递.
public class SortContext {

    private ISortStrategy sortStrategy;

    public SortContext(ISortStrategy sortStrategy) {
        this.sortStrategy = sortStrategy;
    }

    public void doSort(){
    
        // 可以做一些其它逻辑操作
        System.out.println("排序前先过滤为空数据...");
        
        this.sortStrategy.sort();
    }
}

2.7 测试

客户端调用时,需要清楚每种策略的特点,然后选择特定的排序进行调用.

@Test
public void test(){
    SortContext sortContext ;

    // 使用简单排序
    sortContext = new SortContext(new SimpleSort());
    sortContext.doSort();

    // 使用冒泡排序
    sortContext = new SortContext(new BubbleSort());
    sortContext.doSort();

    // 使用快速排序
    sortContext = new SortContext(new QuickSort());
    sortContext.doSort();

}
发布了321 篇原创文章 · 获赞 676 · 访问量 147万+

猜你喜欢

转载自blog.csdn.net/zongf0504/article/details/100103541