策略模式和排序算法

本文探讨了在面临多种排序算法需求时如何利用策略模式进行设计。通过创建一个统一的排序接口,允许不同的排序算法作为策略对象进行互换,以此避免修改原有代码并遵循开闭原则。此外,文章还指出策略模式虽便于拓展和维护,但也可能导致类文件数量增加。从另一个角度看,策略模式实际上体现了多态和面向对象的精髓,难点在于如何在实际业务中抽象出策略接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

常用的排序算法有选择排序,插入排序,冒泡排序,快速排序,归并排序,希尔排序,堆排序这7种。假设现在有7个数组,他们分别需要用到这7种排序方式的其中一个进行排序应该怎么办呢。最常见的办法就是写一个这样的工具类

/**
 * Created by hao on 2016/6/19.
 */
public class SortHelper {
    /**
     * 选择排序
     * @param array
     */
    public static void selectSort(int[] array){
        System.out.println("选择排序");
    }
    /**
     * 插入排序
     * @param array
     */
    public static void insertSort(int[] array){
        System.out.println("插入排序");
    }
    /**
     * 冒泡排序
     * @param array
     */
    public static void bubbleSort(int[] array){
        System.out.println("冒泡排序");
    }
    /**
     * 快速排序
     * @param array
     */
    public static void quickSort(int[] array){
        System.out.println("快速排序");
    }
    /**
     * 归并排序
     * @param array
     */
    public static void mergeSort(int[] array){
        System.out.println("归并排序");
    }
    /**
     * 希尔排序
     * @param array
     */
    public static void shellSort(int[] array){
        System.out.println("希尔排序");
    }
    /**
     * 堆排序
     * @param array
     */
    public static void heapSort(int[] array){
        System.out.println("堆排序");
    }
}

这种方式是可以满足需求的,但是有个不太好的地方:如果我们现在新增了一种排序算法怎么办呢?必须要修改SortHelper类中的代码然后在其中再加一种排序方式,这是违反我们常说的开闭原则的,而且随着排序算法的逐渐增加,SortHelper也会变得更加臃肿。

策略模式

下面我们引入正题,什么是策略模式呢?策略模式模式就是定义一组算法,将每个方法都封装起来,并且使他们之间可以互换。以上面的排序算法为例,我们可以将这些算法都抽象出来,提供一个统一的接口,每种排序算法都去实现这个接口并在其中实现自己的排序算法。当我们使用某种排序算法的时候就可以直接传入这个算法的实现对象就可以了。下面我们还是用代码实现一遍吧

首先定义一个统一的接口

public interface SortStrategy {
    void sort(int[] array);
}

然后每种算法都去实现这个接口

public class SelectSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了选择排序");
    }
}

public class InsertSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了插入排序");
    }
}

public class BubbleSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了冒泡排序");
    }
}

public class MergeSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了归并排序");
    }
}

public class ShellSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了希尔排序");
    }
}

public class HeapSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了堆排序");
    }
}

public class QuickSort implements SortStrategy{
    @Override
    public void sort(int[] array) {
        System.out.println("这里实现了快速排序");
    }
}

我们还需要一个类去将这些类封装一下方便调用

public class SortOperator {
    private SortStrategy strategy;
    public SortOperator(SortStrategy sortStrategy){
        this.strategy=sortStrategy;
    }
    public void Operator(int[] array){
        strategy.sort(array);
    }
}

下面我们可以测试一下策略模式的效果

public class Test {
    public static void main(String[] args){
        SortOperator operator1=new SortOperator(new QuickSort());
        operator1.Operator(null);
        SortOperator operator2=new SortOperator(new MergeSort());
        operator2.Operator(null);
    }
}

运行后结果

这里实现了快速排序
这里实现了归并排序

凡事有利必有弊,策略模式也一样,策略模式封装了底层的算法,可以非常方便的进行拓展和维护。但相应的代价就是类文件增多同时所有的策略类都需要对外暴露。

另一个角度

当你在学习多态的时候一定看过这样的代码

public abstract class Animal {
    abstract void voice();
}

public class Dog extends Animal{
    @Override
    void voice() {
        System.out.println("汪汪。。。");
    }
}

public class Cat extends Animal{
    @Override
    void voice() {
        System.out.println("喵喵");
    }
}

public class Test {
    public static void main(String[] args){
        Animal dog=new Dog();
        dog.voice();
        Animal cat=new Cat();
        cat.voice();
    }
}

有没有发现这跟策略模式简直一毛一样,策略模式本来就是采用了面向对象的继承和多态机制,并没有什么难以理解的地方,难的往往是你如何才能在繁杂的业务逻辑代码中抽离出策略接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值