最实用的设计模式:策略模式的快速理解

Posted Java鱼仔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最实用的设计模式:策略模式的快速理解相关的知识,希望对你有一定的参考价值。

(一)什么是策略模式

策略模式是设计模式中一个相对来说比较好理解,应用也十分广泛的设计模式。在我工作这些年所接触的项目中,有一个项目在整体上就使用了策略模式。在百科上,针对策略模式是这样介绍的:策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。

以某火锅品牌为例,同样是最后的收费环节,学生周末8.8折,工作日的指定时间6.9折,非学生全额支付。同样的收费方式在不同的情况下有不同的计算方式,这里就可以使用策略模式来实现。

(二)策略模式中的几个角色

在策略模式中,有三种角色:

抽象策略(Strategy):定义实现策略所需要的接口。一般是定义接口或者抽象类。

具体策略(ConcreteStrategy):抽象策略的具体实现类,在策略模式中,每个算法都是一个具体策略。

上下文(Context):负责使用策略的角色,屏蔽高层模块对策略的直接访问。

(三)策略模式的具体案例

还是以最开始的火锅店为例子。首先定义一个收费的策略接口,定义收费的方法:

public interface BillingStrategy 
    void billing(BigDecimal amount);

接着写两个具体的策略:

// 周末8.8折
public class StudentWeekend implements BillingStrategy
    @Override
    public void billing(BigDecimal amount) 
        System.out.println("收了"+amount.multiply(new BigDecimal("0.88"))+"元");
    

// 工作日6.9折
public class StudentWorkingDay implements BillingStrategy
    @Override
    public void billing(BigDecimal amount) 
        System.out.println("收了"+amount.multiply(new BigDecimal("0.69"))+"元");
    

接着定义上下文角色,在这个例子中,负责使用策略的角色是火锅店:

public class Restaurant 
    private BillingStrategy billingStrategy;

    public Restaurant(BillingStrategy billingStrategy)
        this.billingStrategy = billingStrategy;
    

    public void billing(BigDecimal amount)
        billingStrategy.billing(amount);
    

最后在Main方法中进行调用:

public class Main 
    public static void main(String[] args) 
        Restaurant restaurant1 = new Restaurant(new StudentWeekend());
        restaurant1.billing(new BigDecimal("200"));

        Restaurant restaurant2 = new Restaurant(new StudentWorkingDay());
        restaurant2.billing(new BigDecimal("200"));
    

从结果可以看出,同样的收费方式,当传入的策略不同时,就可以采取不同的算法。

(四)策略模式在源码中的应用

策略模式在开源代码和JDK源码中的应用十分广泛。

比如TreeMap在构造方法中引入Comparator排序策略,在put方法时根据不同的排序策略执行不同的排序方法:


又比如ThreadPoolExecutor这个线程池的类,在构造方法中传入拒绝策略,在reject方法中根据不同的拒绝策略执行具体的拒绝方法:


(五)策略模式的理解

其实不使用设计模式,一样可以写代码,甚至可以写的更简单,但是设计模式考虑的是代码的扩展和可维护性。

策略模式最大的优点是很方便地替换策略,甚至还可以在程序运行过程中切换策略,也遵循了设计模式中的开闭原则,即对扩展开放,对封闭关闭。缺点是每新增一个策略就需要新增一个类,另外客户端必须知道所有的策略类。

以上是关于最实用的设计模式:策略模式的快速理解的主要内容,如果未能解决你的问题,请参考以下文章

最实用的设计模式:策略模式的快速理解

JavaScript 设计模式之策略模式

案例分析:设计模式与代码的结构特性

java中的设计模式

21种设计模式

java23种设计模式之一: 策略模式