《设计模式》策略模式

这篇具有很好参考价值的文章主要介绍了《设计模式》策略模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

定义

  • 又叫作政策模式,将定义的一系列算法封装起来,使得它们之间可以互相替换,从而让算法的变化不影响到使用算法的用户
  • 属于行为型模式。

策略模式的组成角色

  • 环境类(Context)环境类是使用算法的角色,用来操作策略的上下文环境,屏蔽高层模块(客户端)对策略、算法的直接访问,封装可能存在的变化。
  • 抽象策略(Strategy)规定策略或算法的行为,为所支持的算法声明了抽象方法,是所有具体策略类的父类。
  • 具体策略类(ConcreteStrategy)实现了在抽象策略类中声明的算法。在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

策略模式的 UML 类图
《设计模式》策略模式

🎈情景案例:某数码产品销售店家推送促销优惠活动,推出三种优惠措施:1、店铺商品购买金额满1000元减100元。2、店铺商品购买金额满3000元加购100元送一年保修服务。3、店铺商品金额满5000元打9.5折。

针对以上情景案例使用策略模式设计一个方案:上面三种优惠措施相当于三种具体的策略,记作 Discount1、Discount2 以及 Discount3,它们都实现了共同的接口 Discount,设计的 UML 图如下:

《设计模式》策略模式
Discount 接口

public interface Discount {
    void discount();
}

Discount1 类

public class Discount1 implements Discount {
    @Override
    public void discount() {
        System.out.println("店铺商品购买金额满1000元减100元");
    }
}

Discount2 类

public class Discount2 implements Discount {
    @Override
    public void discount() {
        System.out.println("店铺商品购买金额满3000元加购100元送一年保修服务");
    }
}

Discount3 类

public class Discount3 implements Discount {
    @Override
    public void discount() {
        System.out.println("店铺商品金额满5000元打9.5折");
    }
}

Store 类

public class Store {
    private Discount discount;

    public Store(Discount discount) {
        this.discount = discount;
    }

    public void sale() {
        discount.discount();
    }
}

策略模式的优点

  • 符合开闭原则。用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  • 便于复用。由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。
  • 避免多重条件选择语句。多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑与算法或行为本身的实现逻辑混合在一起,将它们全部硬编码(Hard Coding)在一个庞大的多重条件选择语句中,比直接继承环境类的办法还要原始和落后。

策略模式的缺点

  • 增加维护难度。策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类。
  • 只适用于客户端知道所有的算法或行为的情况。客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 无法同时在客户端使用多个策略类。客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。

策略模式的使用场景

  • 对多个算法进行封装。一个系统需要动态地在几种算法中选择一种,可以将这些算法封装到一个个的具体算法类中。
  • 想要屏蔽算法数据结构,提高保密性与安全性。不希望客户端知道复杂的、与算法相关的数据结构。在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。
  • 不想使用多重条件选择语句。一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现。策略模式将行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句。

🎈策略模式在 JDK 源码中的应用

java.util.Comparator 接口就是一个抽象策略,java.util.Arrays 类就是一个环境类,在调用Arrays.sort(T[] a, Comparator<? super T> c)方法时需要传入具体策略,Arrays 环境类根据具体策略进行排序,该过程的调用链路涉及的代码如下所示:

客户端调用示例如下

Integer[] a = {1, 2, 3, 4, 5};
Arrays.sort(a, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
});
System.out.println(Arrays.toString(a));

Arrays.sort(T[] a, Comparator<? super T> c) 源码

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

TimSort 类中 sort 和 countRunAndMakeAscending 方法源码文章来源地址https://www.toymoban.com/news/detail-429243.html

static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
                      T[] work, int workBase, int workLen) {
     assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;

     int nRemaining  = hi - lo;
     if (nRemaining < 2)
         return;  // Arrays of size 0 and 1 are always sorted

     // If array is small, do a "mini-TimSort" with no merges
     if (nRemaining < MIN_MERGE) {
         int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
         binarySort(a, lo, hi, lo + initRunLen, c);
         return;
     }
     // ...
 }
 private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
                                                    Comparator<? super T> c) {
     assert lo < hi;
     int runHi = lo + 1;
     if (runHi == hi)
         return 1;

     // Find end of run, and reverse range if descending
     if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
         while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
             runHi++;
         reverseRange(a, lo, runHi);
     } else {                              // Ascending
         while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
             runHi++;
     }

     return runHi - lo;
}

到了这里,关于《设计模式》策略模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式-策略模式

    策略模式是一种行为型设计模式,它允许在运行时动态改变对象的行为。在策略模式中,算法被封装在独立的策略类中,使得它们可以互换使用。下面是一个简单的例子: 假设我们有一个计算税收的系统,现在需要计算不同类型的商品的税收,例如书籍、食品和服装。每种商

    2024年02月15日
    浏览(48)
  • 设计模式—策略模式

    目录 一、定义 二、特点 三、优点 四、缺点 五、实例 六.涉及到的知识点 1、一个类里面有哪些东西? 2、类和实例 什么是类? 什么是实例? 什么是实例化? 3、字段和属性 什么是字段? 属性是什么? 属性怎么用呢? 属性有什么作用? 静态属性是什么? 属性和字段的公有

    2024年02月10日
    浏览(52)
  • 《设计模式》策略模式

    定义 : 又叫作 政策模式,将定义的一系列算法封装起来,使得它们之间可以互相替换,从而让算法的变化不影响到使用算法的用户 。 属于 行为型 模式。 策略模式的组成角色 : 环境类(Context) : 环境类是使用算法的角色 ,用来操作策略的上下文环境,屏蔽高层模块(客户

    2024年02月01日
    浏览(44)
  • 设计模式--策略模式

    目录 一.场景 1.1场景 2.2 何时使用  2.3个人理解 二. 业务场景练习  2.1业务: 2.2具体实现 2.3思路   三.总结 3.1策略模式的特点:  3.2策略模式优点 3.3策略模式缺点 1.1场景 许多相关的类仅仅是行为有异,也就是说业务代码需要根据场景不同,切换不同的实现逻辑 一个类定义了

    2024年02月13日
    浏览(40)
  • 【设计模式】 策略模式

    策略模式 (Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,使它们可以相互替换,让客户端代码和算法的具体实现解耦。这样,客户端可以根据不同的需求选择不同的算法,而无需修改原有的代码。 灵活性增强 :策略模式使得算法独立于

    2024年02月14日
    浏览(45)
  • 设计模式-策略模式 Strategy

    该模式最常见的应用场景是,利用它来避免冗长的 if-else 或 switch 分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。 策略模式,英文全称是 Strategy Design Pattern。该模式是这样定义的: Define a family of algorithms, encapsulate each one, and make

    2024年02月20日
    浏览(44)
  • 【设计模式--行为型--策略模式】

    定义 该模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分隔开,并委派给不同的对象对这些算法进行管理。 结构 抽象策略

    2024年02月04日
    浏览(39)
  • 【设计模式 行为型】策略模式

    它允许在运行时根据需要选择算法的行为。该模式通过将算法封装成独立的类,使得它们可以相互替换,而不影响使用算法的客户端代码。 策略模式主要包含以下角色: 环境(Context):环境对象持有一个策略对象的引用,它提供了一个接口用于执行具体的算法。 抽象策略(

    2024年01月20日
    浏览(37)
  • 设计模式再探——策略模式

    最近在做产品的过程中,对于主题讨论回复内容,按照追评次数排序、点赞排序、时间排序等内容做了深入研究,通过策略模式可以很好的进行优化。 1.策略模式简介 2.策略模式的类图 3.策略模式代码 4.策略模式还可以优化的地方 5.策略模式的例子改造 策略模式:它定义了算

    2024年02月13日
    浏览(45)
  • 设计模式之策略模式讲解

    概念:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换,使得算法可以在不影响客户端的情况下发生变化。 抽象策略:对策略进行抽象,定义策略或算法的操作。 具体策略:实

    2024年04月13日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包