设计模式(行为型设计模式——策略模式)

设计模式(行为型设计模式------策略模式)

策略模式

基本定义

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

模式结构

  • Strategy 抽象策略类:所有策略类的父类,为所支持的策略算法声明了抽象方法。

  • ConcreteStrategy 具体策略类:实现了在抽象策略类中声明的方法。

  • Context 环境类:负责使用算法策略,其中维持了一个抽象策略类的引用实例。

代码实现

Strategy 抽象策略类
java 复制代码
public abstract class Discount {
  //计算折扣抽象方法
    abstract double discountPrice(Double originalPrice);
}
ConcreteStrategy 具体策略类
java 复制代码
//首单五折
public class FirstOrderDiscount extends Discount{

    double discount = 0.5; //五折

    @Override
    public double discountPrice(Double originalPrice) {
        return originalPrice * discount;
    }
}
//会员七折
public class MemberDiscount extends Discount{

    double discount = 0.7; //七折

    @Override
    public double discountPrice(Double originalPrice) {
        return originalPrice * discount;
    }
}
//前100名下单八折
public class Top100Discount extends Discount{

    double discount = 0.8; //八折

    @Override
    public double discountPrice(Double originalPrice) {
        return originalPrice * discount;
    }
}
Context 环境类
java 复制代码
public class Context {
  //存储折扣算法
    public static Map<String, Discount> strategyMap = new ConcurrentHashMap<>();

    static {
        for (DiscountType discountType: DiscountType.values()){
            try {
                //基于反射创建全部折扣算法类
                strategyMap.put(discountType.toString(), (Discount) Class.forName(discountType.getClassName()).newInstance());
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    //计算折扣
    public static double discountPrice(String type, Double originalPrice){
        return strategyMap.get(type).discountPrice(originalPrice);
    }

    //计算折扣
    public static double discountPrice(DiscountType type, Double originalPrice){
        return discountPrice(type.toString(), originalPrice);
    }
}

//折扣枚举类
public enum DiscountType {

    MEMBER("会员折扣", "com.yanyuan.gof.behavior.strategy.v2.MemberDiscount"),
    FIRST_ORDER("首次下单", "com.yanyuan.gof.behavior.strategy.v2.FirstOrderDiscount"),
    TOP100("前100名下单", "com.yanyuan.gof.behavior.strategy.v2.Top100Discount");

    private String name;

    private String className;

    DiscountType(String name, String className) {
        this.name = name;
        this.className = className;
    }

    public String getName() {
        return name;
    }

    public String getClassName() {
        return className;
    }
}
测试类
java 复制代码
@Slf4j
public class Test {
    public static void main(String[] args) {
        Double originalPrice = 200d;
        //首次下单
        DiscountType type = DiscountType.FIRST_ORDER;
        double price = Context.discountPrice(type, originalPrice);
        log.info("尊敬的用户: 您所预定的游乐园门票使用 [{}] 折扣, 原价{} RMB, 折后价格 {} RMB ",  type.getName(), originalPrice, price);

        //会员折扣
        type = DiscountType.MEMBER;
        price = Context.discountPrice(type, originalPrice);
        log.info("尊敬的用户: 您所预定的游乐园门票使用 [{}] 折扣, 原价{} RMB, 折后价格 {} RMB ",  type.getName(), originalPrice, price);
    }
}
输出结果

尊敬的用户: 您所预定的游乐园门票使用 [首次下单] 折扣, 原价200.0 RMB, 折后价格 100.0 RMB 尊敬的用户:

您所预定的游乐园门票使用 [会员折扣] 折扣, 原价200.0 RMB, 折后价格 140.0 RMB

优点

  • 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。

  • 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。

  • 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。

  • 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。

  • 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

缺点

  • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。

  • 策略模式造成很多的策略类。

使用场景

  • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。

  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。

  • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。

相关推荐
Bald Baby12 分钟前
JWT的使用
java·笔记·学习·servlet
魔道不误砍柴功17 分钟前
实际开发中的协变与逆变案例:数据处理流水线
java·开发语言
dj244294570740 分钟前
JAVA中的Lamda表达式
java·开发语言
工业3D_大熊1 小时前
3D可视化引擎HOOPS Luminate场景图详解:形状的创建、销毁与管理
java·c++·3d·docker·c#·制造·数据可视化
szc17671 小时前
docker 相关命令
java·docker·jenkins
Stark-C1 小时前
万物皆可Docker,在NAS上一键部署最新苹果MacOS 15系统
macos·docker·策略模式
程序媛-徐师姐1 小时前
Java 基于SpringBoot+vue框架的老年医疗保健网站
java·vue.js·spring boot·老年医疗保健·老年 医疗保健
yngsqq1 小时前
c#使用高版本8.0步骤
java·前端·c#
尘浮生1 小时前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea