首页 > 其他分享 >策略模式

策略模式

时间:2024-01-23 15:33:10浏览次数:21  
标签:totalPrice 策略 double System 模式 println public out

if...else...的优雅写法,可以配合委托模式一起使用

  • 定义:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户
  • 补充定义:处理大量if...else...代码
  • 类型:行为型
  • 适用场景:
    • 系统有很多类,而他们的区别仅仅在于他们的行为策略不同
    • 一个系统需要动态地在几种算法中选择一种
  • 优点:
    • 符合开闭原则
    • 避免使用多重条件转移语句
    • 提高算法的保密性和安全性
  • 缺点:
    • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
    • 产生很多策略类
  • 相关设计模式
    • 策略模式和工厂模式:工厂模式是创建型的,策略模式是行为型的,工厂模式接收指令创建符合要求的实例对象,而策略模式接收创建好的对象从而实现不同的行为
    • 策略模式和状态模式:对于策略模式客户端需要知道到底选择哪个策略,而在使用状态模式时客户端不需要关心具体的状态,它的这些状态会自动装换

公式计算

/**
 * <p>定义计算接口,提供根据公式(字符串)计算值的方法</p>
 *
 */
public interface ICalculator {

    /**
     * <p>根据公式字符串,计算得出值</p>
     *
     * @param formula 公式
     * @return 值
     */
    double calculate(String formula);

}
/**
 * <p>乘法运算实现乘法公式的结果计算</p>
 *
 */
public class Mul implements ICalculator {

    @Override
    public double calculate(String formula) {
        double[] valArray = CalculatorHelper.getValArray(formula, "\\*");
        return valArray[0] * valArray[1];
    }

}
/**
 * <p>加法运算实现加法公式的结果计算</p>
 *
 */
public class Plus implements ICalculator {

    @Override
    public double calculate(String formula) {
        double[] valArray = CalculatorHelper.getValArray(formula, "\\+");
        return valArray[0] + valArray[1];
    }

}
/**
 * <p>减法运算实现减法公式的结果计算</p>
 *
 */
public class Sub implements ICalculator {

    @Override
    public double calculate(String formula) {
        double[] valArray = CalculatorHelper.getValArray(formula, "-");
        return valArray[0] - valArray[1];
    }

}
/**
 * <p>计算辅助类,主要提取公式中的数数组</p>
 *
 */
public class CalculatorHelper {

    public static double[] getValArray(String formula, String splitChar) {
        //记得消除空格
        String array[] = formula.trim().split(splitChar);
        double arrayDouble[] = new double[2];
        arrayDouble[0] = Double.parseDouble(array[0]);
        arrayDouble[1] = Double.parseDouble(array[1]);
        return arrayDouble;
    }

}

 

UML

商场打折

/**
 * <p>定义价格计算策略接口,为每一个策略类提供统一的计算折扣价钱的方法</p>
 *
 */
public interface ICalculatePrice {

    /**
     * <p>根据商品的实际总价计算得到商品折后的价钱</p>
     *
     * @param totalPrice 实际商品总价
     * @return 折后价
     */
    double getDiscountedPrice(double totalPrice);

}
/**
 * <p>电商节 - 6.18 -- 满618元减99,满1000元打8.5折</p>
 *
 */
public class DianShang618 implements ICalculatePrice {

    @Override
    public double getDiscountedPrice(double totalPrice) {

        if (totalPrice >= 618) {
            return totalPrice - 99;
        }

        if (totalPrice >= 1000) {
            return totalPrice * 0.85;
        }

        return totalPrice;
    }

}
/**
 * <p>商品满减活动 -- 满300元减100元</p>
 *
 */
public class Man300Jian100 implements ICalculatePrice {

    @Override
    public double getDiscountedPrice(double totalPrice) {

        // 全场消费满300元,减100元
        if (totalPrice >= 300) {
            return totalPrice - 100;
        }
        return totalPrice;
    }

}
/**
 * <p>天猫双11购物狂欢节 -- 满500减少166,满1000元随机打折,有可能免单哦</p>
 *
 */
public class Shuang11 implements ICalculatePrice {

    // 分别是免单、6.5折、7.5折、8.5折和9折
    private static double[] discount = new double[]{0.0, 0.65, 0.75, 0.85, 0.90};

    @Override
    public double getDiscountedPrice(double totalPrice) {

        if (totalPrice >= 500 && totalPrice < 1000) {
            return totalPrice - 166;
        }

        if (totalPrice >= 1000) {
            Random random = new Random();
            return totalPrice * (discount[random.nextInt(5)]);
        }
        return 0;
    }

}
/**
 * <p>价格上下文类</p>
 * <p>对用户暴露计算折后价钱的方法,由用户选择使用具体的打折策略类来计算最终的商品价钱</p>
 *
 */
public class PriceContext {

    private ICalculatePrice price;

    public PriceContext(ICalculatePrice price) {
        this.price = price;
    }

    public double discount(double totalPrice) {
        double discountedPrice = price.getDiscountedPrice(totalPrice);
        if (0.0 == discountedPrice) {
            System.out.println("恭喜您,您本次消费免单!");
        }
        return discountedPrice;
    }

}

 

UML

测试

/**
 * <p>策略模式测试</p>
 *
 */
public class StrategyTest {

    public static void main(String[] args) {

        // 1、 策略模式☞运算公式结果计算
        plus();
        sub();
        mul();

        // 2、 策略模式☞商场打折
        man300jian100();
        dianShang618();
        shuang11();
    }

    private static void plus() {
        System.out.println("===============2+ 8 乘法运算");
        ICalculator calculator = new Plus();
        double calculate = calculator.calculate("2+ 8");
        System.out.println("2+ 8 = " + calculate);
    }

    private static void sub() {
        System.out.println("===============2 - 8 减法运算");
        ICalculator calculator = new Sub();
        double calculate = calculator.calculate("2 - 8");
        System.out.println("2 - 8 = " + calculate);
    }

    private static void mul() {
        System.out.println("===============2*8 乘法运算");
        ICalculator calculator = new Mul();
        double calculate = calculator.calculate("2*8");
        System.out.println("2*8 = " + calculate);
    }

    private static void man300jian100() {

        System.out.println("===============全场满300减100!");
        double totalPrice = 450.0;
        System.out.println("商品原价:" + totalPrice + "¥");
        PriceContext price = new PriceContext(new Man300Jian100());
        System.out.println("商品折后的价钱:" + price.discount(totalPrice) + "¥");

    }

    private static void dianShang618() {

        System.out.println("===============电商节6.18欢快购!");
        double totalPrice = 700.0;
        System.out.println("商品原价:" + totalPrice + "¥");
        PriceContext price = new PriceContext(new DianShang618());
        System.out.println("商品折后的价钱:" + price.discount(totalPrice) + "¥");

        totalPrice = 1024.0;
        System.out.println("商品原价:" + totalPrice + "¥");
        System.out.println("商品折后的价钱:" + price.discount(totalPrice) + "¥");
    }

    private static void shuang11() {

        System.out.println("===============双11全场嗨翻购!");
        double totalPrice = 623.0;
        System.out.println("商品原价:" + totalPrice + "¥");
        PriceContext price = new PriceContext(new Shuang11());
        System.out.println("商品折后的价钱:" + price.discount(totalPrice) + "¥");

        totalPrice = 1500.0;
        System.out.println("商品原价:" + totalPrice + "¥");
        System.out.println("商品折后的价钱:" + price.discount(totalPrice) + "¥");
    }


    /**
     *
     * 百科上如此介绍策略模式:
     * 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
     * 策略模式让算法独立于使用它的客户而独立变化。
     *
     * 通过上述两个算法计算的例子,我们可以领略到策略模式的好处:
     * (1)用户或算法使用者可以选择不同的算法类来实现自己业务算法的需要
     * (2)开发者扩展新的算法类,只需要新建一个类实现calculate方法即可,扩展相当方便
     * (4)总结就是,遵守了"开闭原则",对扩展开放,对修改关闭!
     * 缺点:
     * (1)如果基于选择的策略模式很多的话,这就意味着子类有很多,维护起来增加复杂性
     * (2)对于使用者来说,他必须知道全部的策略类,才可以做到策略的任意切换
     */

}
============运行结果===============
===============2+ 8 乘法运算
2+ 8 = 10.0
===============2 - 8 减法运算
2 - 8 = -6.0
===============2*8 乘法运算
2*8 = 16.0
===============全场满300减100!
商品原价:450.0¥
商品折后的价钱:350.0¥
===============电商节6.18欢快购!
商品原价:700.0¥
商品折后的价钱:601.0¥
商品原价:1024.0¥
商品折后的价钱:925.0¥
===============双11全场嗨翻购!
商品原价:623.0¥
商品折后的价钱:457.0¥
商品原价:1500.0¥
恭喜您,您本次消费免单!
商品折后的价钱:0.0¥

 

源码中的应用

  • java.util.Comparator:这个比较器就是一个抽象的策略,它提供了compare()和equals()方法,所有的策略都要实现这两个方法,它内部还有一堆具体的策略可供使用
public interface Comparator<T> {
    ...
    int compare(T o1, T o2);
    ...
    boolean equals(Object obj);
    ...
}

 

标签:totalPrice,策略,double,System,模式,println,public,out
From: https://www.cnblogs.com/wangzhilei-src/p/17982588

相关文章

  • MySQL密码过期策略
    如果要设置密码永不过期的全局策略,可以这样:(注意这是默认值,配置文件中可以不声明)[mysqld]default_password_lifetime=0禁用密码过期:ALTERUSER'testuser'@'localhost'PASSWORDEXPIRENEVER;......
  • Nginx配置ThinkPHP3.1的PATHINFO模式
    server{listen8156;#监听端口(根据自己的需求更改)server_namelocalhost;#域名root/www/php;indexindex.htmlindex.htmindex.php;location~.*\.php/?.*${fastcgi_indexindex.php;fastcgi_pass127.0.0.1:9000;includefa......
  • 一种行之有效的防错策略:在支付系统中实施防呆设计的实践
    聊个支付人都会碰到的问题:资损防控。做支付如果还没有碰到过资损,那就是做得时间还不够久。资损防控是一个很大的话题,需要开几篇文章才能讲完,今天只从一件小事入手聊一个简单而又行之有效的防错策略:防呆设计的实践。1.一个线上事故曾经处理过一个资损事件,很典型,值得说道说道。一个......
  • Appium PO模式UI自动化测试框架——设计与实践
    AppiumPO模式UI自动化测试框架——设计与实践1.目的  相信做过测试的同学都听说过自动化测试,而UI自动化无论何时对测试来说都是比较吸引人的存在。相较于接口自动化来说它可以最大程度的模拟真实用户的日常操作与特定业务场景的模拟,那么存在即合理,自动化UI测试自然也是广......
  • 设计模式:行为型模式(套路:甩锅大法)
    文章目录行为型模式(BehavioralPattern)1.职责链模式(ChainofResponsibility)1.1.定义1.2.结构1.3.代码实现1.4.优缺点1.5.使用场景1.6.总结2.命令模式(Command)2.1.定义2.2.结构2.3.时序图2.4.代码实现2.5.优缺点2.6.使用场景2.7.总结3.解释器模式(Inter......
  • 独立开发一款在线浏览器书签管理平台,网页剪藏,专注阅读模式-藏趣云浏览器书签
    藏趣云-阅读模式重磅来袭发布  新增功能模块大家好,今天给大家带来一个藏趣云的全新功能,网页阅读功能,和聚合搜索功能。网页阅读聚合搜索百度搜索:藏趣云了解更多  官网地址:藏趣云官网帮助文档与下载地址:下载地址和帮助文档 藏趣云介绍藏趣云是一款跨平台的......
  • Spring Cloud 系列:Seata 中TCC模式具体实现
    概述https://seata.io/zh-cn/docs/dev/mode/tcc-modehttps://seata.io/zh-cn/docs/user/mode/tccTCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复。需要实现三个方法:Try:资源的检测和预留;Confirm:完成资源操作业务;要求Try成功Confirm一......
  • 设计模式之策略模式
    1.定义定义一系列算法,并将每个算法封装成一个独立的类,使它们可以相互替换2.口语化表述策略模式通常适用于需要根据不同情况选择不同算法的场景,例如排序算法、计算税费等现在说说排序算法,常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等,每种排序算法......
  • 设计模式——组合模式
    定义组合(CompositePattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。节点组合模式结构为一颗二叉树,存在三种节点Component:组合模式......
  • 【Python进阶】Python设计模式
    设计模式介绍什么是设计模式设计模式是面对各种问题进行提炼和抽象而形成的解决方案。这些设计方案是前人不断试验,考虑了封装性、复用性、效率、可修改、可移植等各种因素的高度总结。它不限于一种特定的语言,它是一种解决问题的思想和方法为什么要用设计模式按照设计模式编写......