设计模式|策略模式

本文介绍了策略模式的基本概念、角色及其实现,通过一个排序操作的例子展示了如何使用策略模式提高代码的灵活性和可维护性,同时讨论了其优缺点和适用场景。
摘要由CSDN通过智能技术生成

  题外话:

        本文实非大佬们的科普著作,而是犬余学习过程中的笔记略作润色,内容如有错误或不当之处,欢迎指正。
  再此也小推一下本人的公众号,记录一下学习过程,立个flag:坚持学习,每周一更,欢迎监督~

正文:

        策略模式(Strategy Pattern)是一种行为型(Behavioral Pattern)的设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端。这种模式是为了实现同一个目标,有多种解决方案或算法的情况下使用的。在策略模式中,主要涉及三类角色:

    a. 策略接口(Strategy Interface):这是一个接口,定义了所有支持的算法的公共操作。不同的算法以不同的方式实现这个接口。

    b. 具体策略(Concrete Strategies):实现策略接口的类,提供具体的算法实现。每一个类封装了一种具体的算法或行为。

    c. 上下文环境(Context):上下文是使用策略的类。它包含一个策略接口的引用,用于运行时切换策略。上下文不知道具体策略的实现细节,它通过策略接口与策略交互。

    策略模式的关键点是使得算法可以独立于客户端而变化,也就是说,增加新的算法或者改变算法对客户端没有影响。这样做的好处是可以避免多重条件选择语句,使得代码更加清晰,提高代码的可维护性,并且可以更容易地扩展新的算法。

        在软件开发过程中,我们经常需要对某个数组进行排序操作,现在我们需要提供一个工具,使之 可以根据需要动态地切换排序算法,我们写出的代码可能是这样的:

public static List<Integer> sort(List<Integer> list, String algorithm){
    if("mp".equals(algorithm)){
        System.out.println("使用了冒泡排序");
    }else if("ks".equals(algorithm)){
        System.out.println("使用了快速排序");
    }else if("xz".equals(algorithm)){
        System.out.println("使用了选择排序");
    }
    return list;
}

        按照需求来讲,我们确实实现了需要的功能,但是随着需求的迭代,排序算法的总类必然会越来越多,这也就导致了这个sort方法中的ifelse语句越来越长,越来越不易维护;此时带入策略模式的思想,我们会发现,不同的排序算法对我们来讲其实就是不同的策略,那么我们开始对这个方法做一些改进:

    首先定义一个用于排序的策略接口:

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

    然后实现具体排序类:

public class BubbleSortStrategy implements SortStrategy{
    @Override
    public List<Integer> sort(List<Integer> list) {
        System.out.println("使用了冒泡排序");
        return list;
    }
}

public class QuickSortStrategy implements SortStrategy{
    @Override
    public List<Integer> sort(List<Integer> list) {
        System.out.println("使用了快速排序");
        return list;
    }
}

public class SelectionSortStrategy implements SortStrategy{
    @Override
    public List<Integer> sort(List<Integer> list) {
        System.out.println("使用了选择排序");
        return list;
    }
}

接下来,定义我们排序工具的上下文,指定需要的策略并使用指定的策略进行排序:

public class SortContext {
    SortStrategy sortStrategy;

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

    public void setSortStrategy(SortStrategy sortStrategy) {
        this.sortStrategy = sortStrategy;
    }

    public List<Integer> sort(List<Integer> list){
        return this.sortStrategy.sort(list);
    }
}

        此时,我们可以在客户端代码中使用策略模式来执行排序操作:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
   
    SortContext sortContext = new SortContext(new BubbleSortStrategy());
    sortContext.sort(list);
}

        在上述代码中,SortStrategy接口即为前面提到过的策略接口(Strategy Interface),它定义了所有排序算法公共功能——排序;而BubbleSortStrategy,QuickSortStrategy以及SelectionSortStrategy三个排序策略的实现类则作为具体策略(Concrete Strategies),他们各自实现了自己的排序算法,在后续的维护中,只需要按需增加新的实现策略即可,而不再需要像之前一样修改公共的ifelse区域代码了;最后的SortContext则扮演着上下文环境(Context)的角色,在运行时可以通过setSortStrategy方法动态地切换使用的排序策略。

        而经过以上的说明以及示例,我们可以体会到策略模式具有的一些优点:

  1. 灵活性:策略模式允许在运行时动态地切换算法或策略,这使得代码更加灵活,可以根据需要选择不同的实现。
  2. 可维护性:由于每种策略都有自己的类,因此添加新策略或修改现有策略不会影响其他部分的代码,从而提高了代码的可维护性。
  3. 可扩展性:策略模式使得新的策略可以很容易地添加到系统中,而不需要修改现有的代码。
  4. 降低耦合度:将不同的算法或策略封装在各自的类中,使得它们与客户端代码之间的耦合度降低,提高了代码的可重用性。 

         与此同时,它又不可避免地产生了一些缺点

  1. 增加了类的数量:每个具体策略都需要一个单独的类,这可能会导致类的数量增加,特别是在策略较多的情况下。

  2. 客户端必须知道所有的策略:客户端必须了解所有可用的策略,并且负责选择合适的策略,这可能会增加客户端代码的复杂性。

    总的来说,策略模式在需要在运行时动态选择算法或策略的情况下非常有用,可以提高代码的灵活性和可维护性。然而,在某些情况下,可能会增加类的数量和客户端代码的复杂性。因此,在使用策略模式时,需要权衡其优点和缺点,选择最适合的设计方案。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值