笨蛋学设计模式行为型模式-策略模式【16】

发布时间:2024年01月21日

8.3策略模式??????

8.3.1概念

? 策略模式定义了一系列算法(这些算法完成的是相同的工作,只是实现不同),允许在运行时动态地选择算法或行为,并将每个算法封装成独立的策略对象,使它们可以相互替换,而且算法的变化不会影响使用算法的客户。

8.3.2场景

? 在购物平台上,我们需要实现一个促销活动功能。可以通过使用策略模式来实现不同类型的促销策略,比如折扣、满减、赠品等,每个促销策略可以被封装成一个独立的策略类,客户端根据不同的促销需求来选择不同的策略进行结算。

8.3.3优势 / 劣势

  • 可扩展性:可以轻松地添加新的策略类,无需修改已有的代码
  • 遵循开闭原则:对扩展开发,对修改关闭,通过定义接口或抽象类作为策略类的共同父类,客户端可以针对抽象策略类编程,而无需关系具体策略类的实现细节
  • 算法独立:将算法的选择和实现分离,使得算法可以独立于客户端变化,客户端就可以根据需求选择不同的策略

  • 代码复杂性增加:会增加系统中类和对象的数量,导致代码的复杂度增加
  • 客户端复杂性增加:客户端必须了解所有的策略类,以此来自行决定使用哪个策略类

8.3.4策略模式可分为

  • 策略类Strategy:定义所有支持的算法的公共解耦
  • 具体策略类ConcreteStrategy:实现了策略接口,提供具体的算法实现
  • 上下文类Context:包含一个策略实例,并在需要时调用策略对象的方法

8.3.5策略模式

package com.technologystatck.designpattern.mode.strategy;

public class Strategys {
    public static void main(String[] args) {

        //创建上下文对象,并设置具体的策略
        Context contextA = new Context(new ConcreteStrategyA());

        //执行策略
        contextA.contextInterface();

        Context contextB = new Context(new ConcreteStrategyB());
        contextB.contextInterface();

    }
}

//1.抽象策略抽象类
abstract class Strategy {
    //抽象方法
    public abstract void algorithmInterface();
}

//2.具体策略类1
class ConcreteStrategyA extends Strategy{
    @Override
    public void algorithmInterface() {
        System.out.println("Strategy A");
    }
    //具体的策略1执行逻辑
}

//3.具体策略类2
class ConcreteStrategyB extends Strategy{

    @Override
    public void algorithmInterface() {
        System.out.println("Strategy B");
    }
    //具体的策略2执行逻辑
}

//4.上下文类
class Context {
    private Strategy strategy;

    //设置具体的策略
    public Context(Strategy strategy){
        this.strategy=strategy;
    }

    //执行策略
    public void contextInterface(){
        strategy.algorithmInterface();
    }
}

8.3.6实战

8.3.6.1题目描述

小明家的超市推出了不同的购物优惠策略,你可以根据自己的需求选择不同的优惠方式。其中,有两种主要的优惠策略:

  1. 九折优惠策略:原价的90%。
  2. 满减优惠策略:购物满一定金额时,可以享受相应的减免优惠。

具体的满减规则如下:

满100元减5元

满150元减15元

满200元减25元

满300元减40元

请你设计一个购物优惠系统,用户输入商品的原价和选择的优惠策略编号,系统输出计算后的价格。

8.3.6.2输入描述

输入的第一行是一个整数 N(1 ≤ N ≤ 20),表示需要计算优惠的次数。

接下来的 N 行,每行输入两个整数,第一个整数M( 0 < M < 400) 表示商品的价格, 第二个整数表示优惠策略,1表示九折优惠策略,2表示满减优惠策略

8.3.6.3输出描述

每行输出一个数字,表示优惠后商品的价格

8.3.6.4代码
package com.technologystatck.designpattern.mode.strategy;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        //读取需要计算优惠的次数
        int nums = Integer.parseInt(scanner.nextLine());

        for(int i=0;i<nums;i++){
            //读取商品价格和优惠策略
            String[] inputs = scanner.nextLine().split(" ");
            int price = Integer.parseInt(inputs[0]);
            int strategyType = Integer.parseInt(inputs[1]);

            //根据优惠策略设置相应的打折策略
            DiscountStrategy discountStrategy=null;
            switch (strategyType){
                case 1:
                    discountStrategy=new DiscountStrategy9();
                    break;
                case 2:
                    discountStrategy=new DiscountStrategyFull();
                    break;
                default:
                    System.out.println("输入有误");
                    break;
            }
            //设置打折策略
            //实例化一个上下文类
            DiscountContext context = new DiscountContext();
            //设置策略
            context.setStrategy(discountStrategy);

            //计算优惠后的价格
            int discountPrice = context.applyDiscount(price);
            System.out.println(discountPrice);
        }
    }
}

//抽象购物优惠策略接口
interface DiscountStrategy {
    //抽象方法
    int applyDiscount(int originalPrice);
}

//9折优惠策略
class DiscountStrategy9 implements DiscountStrategy {
    @Override
    public int applyDiscount(int originalPrice) {
        return (int) Math.round(originalPrice * 0.9 );
    }
}
//满减优惠策略
class DiscountStrategyFull implements DiscountStrategy {
    //定义满足的价格
    private int[] thresholds ={100,150,200,300};
    //定义折扣力度
    private int[] discounts={5,15,25,40};
    @Override
    public int applyDiscount(int originalPrice) {
        //遍历价格表
        for(int i=thresholds.length-1;i>=0;i--){
            //若有满足的条件的价格
            if(originalPrice >=thresholds[i]){
                //就不再继续遍历,直接返回优惠后的价格
                //即优惠价=原价-满减多少的价格
                return originalPrice-discounts[i];
            }
        }
        return originalPrice; //没有满足条件的优惠,返回原价格
    }
}

//上下文类
class DiscountContext {
    private DiscountStrategy strategy;
    //设置set方法

    public void setStrategy(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    //输入原价格
    public int applyDiscount(int originalPrice){
        return strategy.applyDiscount(originalPrice);
    }
}

8.3.7总结

  • 优点:避免代码的重复,使得每个算法都可以独立于使用它的客户端,增加了选择
  • 总结:定义了一系列的算法,将每个算法封装起来,根据不同的应用场景选择算法中最合适的算法
  • 场景
    • 系统根据业务场景需要动态地在几种算法中选择一种时
    • 代码中存在大量条件按判断,且条件判断的区别仅仅在于行为,可以使用策略模式消除这些条件语句
文章来源:https://blog.csdn.net/YSL_Monet/article/details/135699658
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。