首页 > 编程语言 >14.(行为型模式)java设计模式之策略模式

14.(行为型模式)java设计模式之策略模式

时间:2023-01-16 20:34:06浏览次数:40  
标签:java 策略 productOrder double ProductOrder 模式 算法 设计模式 public

一、什么是策略模式

    策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

  • 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
  • 淘宝天猫双十一,正在搞活动有打折的、有满减的、有返利的等等,这些算法只是一种策略,并且是随时都可能互相替换的,我们就可以定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

二、策略模式的实现方式

模式结构分析:

  • Context上下文:屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化
  • Strategy策略角色∶抽象策略角色,是对策略、算法家族的抽象,定义每个策略或算法必须具有的方法和属性
  • ConcreteStrategy具体策略角色:用于实现抽象策略中的操作,即实现具体的算法

类关系图:

统一模型:

代码实现:

查看代码

/*
*  具体的商品信息
* */
@Data
public class ProductOrder {
    private double oldPrice;
    private int userId;
    private int productId;
    public ProductOrder(double oldPrice, int userId, int productId){
        this.oldPrice = oldPrice;
        this.userId = userId;
        this.productId = productId;
    }
}
/*
* 需要计算价格的一个策略
* */
public abstract class Strategy {
    public abstract double computePrice(ProductOrder productOrder);
}
public class NormalActivity extends  Strategy {
    @Override
    public double computePrice(ProductOrder productOrder) {
        return productOrder.getOldPrice();
    }
}
/*
* 进行折扣
* */
public class DiscountActivity extends Strategy {
    /**
     * 具体的折扣
     */
    private double rate;
    public DiscountActivity(double rate){
        this.rate = rate;
    }
    @Override
    public double computePrice(ProductOrder productOrder) {
        return productOrder.getOldPrice()*rate;
    }
}
/*
* 传⼊优惠券
* */
public class CouponActivity extends  Strategy{
    private double couponPrice;
    public  CouponActivity(double couponPrice){
        this.couponPrice = couponPrice;
    }
    @Override
    public double computePrice(ProductOrder productOrder) {
        if(productOrder.getOldPrice()>couponPrice){
            return productOrder.getOldPrice()-couponPrice;
        }else{
            return 0;
        }
    }
}
/*
* 使用中这种策略的上下文
* */
public class PromotionContext {
    private Strategy strategy;
    public  PromotionContext(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 根据策略计算最终的价格
     * @param productOrder
     * @return
     */
    public double executeStrategy(ProductOrder productOrder){
        return strategy.computePrice(productOrder);
    }
}

测试用例:

/*
 * 策略模式
 * */
@Test
public void strategy() {
    ProductOrder productOrder = new ProductOrder(800, 1, 32);
    PromotionContext context;
    double finalPrice;
    //没活动
    context = new PromotionContext(new NormalActivity());
    finalPrice = context.executeStrategy(productOrder);
    System.out.println("NormalActivity =" + finalPrice);
    //折扣策略
    context = new PromotionContext(new DiscountActivity(0.8));
    finalPrice = context.executeStrategy(productOrder);
    System.out.println("DiscountActivity =" + finalPrice);
    //优惠券抵扣
    context = new PromotionContext(new CouponActivity(100));
    finalPrice = context.executeStrategy(productOrder);
    System.out.println("VoucherActivity ="+finalPrice);
}

测试结果:

NormalActivity =800.0
DiscountActivity =640.0
VoucherActivity =700.0

方法评估:

优点:

  • 满足开闭原则,当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例。
  • 避免使用多重条件判断,如果不用策略模式可能会使用多重条件语句不利于维护,和工厂模式的搭配使用可以很好地消除代码if-else的多层嵌套(工厂模式主要是根据参数,获取不同的策略)。

缺点:

  • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
  • 对外暴露了类所有的行为和算法,行为过多导致策略类膨胀

标签:java,策略,productOrder,double,ProductOrder,模式,算法,设计模式,public
From: https://www.cnblogs.com/q994321263/p/17053569.html

相关文章

  • 创建设计模式
    一、前言最近看了一些有关设计模式的相关书籍和博客,学习了几种常用的设计模式,归纳总结一下学习笔记。二、什么是创建型设计模式?在软件工程中,创建型设计模式是处理对象创......
  • Java面试题Day09
    1.创建线程的三种方法(1)继承Thread类,重写父类run()方法.(2)实现runnable接口(3)使用ExcutorService,Callable,Future实现有返回结果的多线程(JDK1.5以后)2.多线程同......
  • JavaScript学习笔记—函数中的this
    this函数在执行时,JS解析器每次都会传递进一个隐含的参数,即thisthis会指向一个对象,所指向的对象会根据函数调用方式的不同而不同(1)以函数形式调用时,this指向的是window(2......
  • 【问题解决】Tomcat启动服务时提示Filter初始化或销毁出现java.lang.AbstractMethodEr
    问题背景最近在开发项目接口,基于SpringBoot2.6.8,最终部署到外置Tomcat8.5.85下,开发过程中写了一个CookieFilter,实现javax.servlet.Filter接口,代码编译期正常。部署到外......
  • 【Javaweb】动态web工程目录介绍
    src存放自己编写的Java源代码web专门用来存放web工程的资源文件(html页面、css文件、js文件等等)WEB-INF是一个受服务器保护的目录,浏览器无法直接访问此目录的内容web.......
  • JAVA基础强化Day3
    总结运算符(1) 算术运算符:+-*/++--(2) 逻辑运算符:① 逻辑与&,逻辑非!,逻辑或|② 逻辑与短路&&,逻辑或短路||③ 区别:&无论前面是真假后面的语句都会执行,无断......
  • JavaScript 回调函数
    函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回;回调函数回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当......
  • Docker网络模式
    Docker网络作用:容器间的互联和通信以及端口映射,容器IP变动时候可以通过服务名直接网络通信而不受到影响常用基本命令dockernewwork--helpdockernetworkls#查看网络......
  • 7.java变量
    7.java变量7.1变量定义​Java语言中,所有的变量在使用前必须声明,声明之后使用之前必须进行赋值。声明变量的基本格式如下:​typevariable[=value][,vari......
  • 【Javaweb】tomcat目录介绍
    bin专门用来存放tomcat服务器的可执行程序conf专门用来存放tomcat服务器的配置文件lib专门用来存放tomcat服务器的jar包logs专门用来存放tomcat服务器运行时输出的......