策略模式

70 阅读2分钟

策略模式

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


结构

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。

  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

image.png

代码

package wnan.strategy;

/*****UTF-8*****
 * Description: 抽象策略 折扣接口
 * Author: wnan
 * Create Date: 2024/10/5 10:38
 * Proverbs: 吃得苦中苦,方为人上人
 */
public interface Discount {
    void show();
}
package wnan.strategy;

/*****UTF-8*****
 * Description: 具体策略角色 折扣A
 * Author: wnan
 * Create Date: 2024/10/5 10:39
 * Proverbs: 吃得苦中苦,方为人上人
 */
public class DiscountA implements Discount{
    @Override
    public void show() {
        System.out.println("买一送一");
    }
}
package wnan.strategy;

/*****UTF-8*****
 * Description: 具体策略角色 折扣B
 * Author: wnan
 * Create Date: 2024/10/5 10:40
 * Proverbs: 吃得苦中苦,方为人上人
 */
public class DiscountB implements Discount{
    @Override
    public void show() {
        System.out.println("打一折");
    }
}
package wnan.strategy;

/*****UTF-8*****
 * Description: 环境角色 售货员类
 * Author: wnan
 * Create Date: 2024/10/5 10:42
 * Proverbs: 吃得苦中苦,方为人上人
 */
public class SalesMan {
    // 持有抽象策略角色的引用
    private Discount discount;

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

    public void salesManShow(){
        System.out.println("售货员介绍折扣:");
        discount.show();
    }
}
package wnan.strategy;

/*****UTF-8*****
 * Description: 策略模式
 * Author: wnan
 * Create Date: 2024/10/5 10:36
 * Proverbs: 吃得苦中苦,方为人上人
 */
public class Client {
    public static void main(String[] args) {
        // 折扣A
        SalesMan man=new SalesMan(new DiscountA());
        man.salesManShow();

        // 折扣B
        SalesMan man1 = new SalesMan(new DiscountB());
        man1.salesManShow();
    }
}

源码 design_pattern

分析

优点:

  • 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。

  • 易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“

  • 避免使用多重条件选择语句(if-else),充分体现面向对象设计思想。

缺点:

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

  • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。