【Java知识】Java进阶-策略模式实现

策略模式

      • 主要角色
      • 示例代码
      • 优点
      • 缺点
      • 适用场景
    • 相关文献

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换。策略模式使得算法可以独立于使用它的客户端而变化。

主要角色

  1. 策略接口(Strategy)

    • 这是一个抽象类或接口,定义了所有支持的算法的公共接口。
    • 上下文使用这个接口来调用算法。
  2. 具体策略(Concrete Strategy)

    • 实现了策略接口的具体算法。
    • 具体策略类提供了具体的算法实现,并且可以被上下文使用。
  3. 上下文(Context)

    • 持有一个策略接口的引用。
    • 客户端通过上下文来调用算法。上下文在运行时可以动态地改变策略对象,从而改变算法。

示例代码

以下是一个简单的策略模式示例,用于计算不同折扣策略下的价格。

// 策略接口
interface DiscountStrategy {
    double calculateDiscount(double price);
}

// 具体策略:无折扣
class NoDiscountStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price;
    }
}

// 具体策略:百分比折扣
class PercentageDiscountStrategy implements DiscountStrategy {
    private double percentage;

    public PercentageDiscountStrategy(double percentage) {
        this.percentage = percentage;
    }

    @Override
    public double calculateDiscount(double price) {
        return price * (1 - percentage / 100);
    }
}

// 具体策略:固定金额折扣
class FixedAmountDiscountStrategy implements DiscountStrategy {
    private double amount;

    public FixedAmountDiscountStrategy(double amount) {
        this.amount = amount;
    }

    @Override
    public double calculateDiscount(double price) {
        return price - amount;
    }
}

// 上下文
class ShoppingCart {
    private DiscountStrategy discountStrategy;

    public ShoppingCart(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public double calculateTotal(double price) {
        return discountStrategy.calculateDiscount(price);
    }
}

// 客户端代码
public class StrategyPatternDemo {
    public static void main(String[] args) {
        double price = 100.0;

        ShoppingCart cart = new ShoppingCart(new NoDiscountStrategy());
        System.out.println("Total price with no discount: " + cart.calculateTotal(price));

        cart.setDiscountStrategy(new PercentageDiscountStrategy(10));
        System.out.println("Total price with 10% discount: " + cart.calculateTotal(price));

        cart.setDiscountStrategy(new FixedAmountDiscountStrategy(15));
        System.out.println("Total price with $15 discount: " + cart.calculateTotal(price));
    }
}

优点

  1. 算法自由切换:策略模式使得算法可以独立于使用它的客户端而变化。
  2. 扩展性好:通过增加新的策略类,可以很容易地扩展系统。
  3. 避免多重条件判断:使用策略模式可以避免在客户端代码中使用多重条件判断来选择算法。

缺点

  1. 策略类数量增加:当策略数量较多时,会增加类的数量,从而增加系统的复杂性。
  2. 客户端需要了解策略:客户端需要知道有哪些策略可供选择,并了解如何创建和配置这些策略对象。

适用场景

  • 当有多种算法需要实现,并且这些算法可以互换时。
  • 当算法在运行时需要动态地改变时。
  • 当算法的实现需要隐藏,或者算法的实现细节对客户端不可见时。

策略模式是一种非常灵活的设计模式,适用于需要动态选择算法的场景。通过封装算法,策略模式使得算法的变化不会影响到使用它的客户端代码。

相关文献

【知识科普】一篇文章教你学会设计模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/925147.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC |(一)SpringMVC概述

文章目录 📚SpringMVC概述🐇三层架构🐇异步调用 📚SpringMVC入门案例🐇入门案例🐇注意事项 📚小结 学习来源:黑马程序员SSM框架教程_SpringSpringMVCMaven高级SpringBootMyBatisPlus…

Android 桌面窗口新功能推进,聊一聊 Android 桌面化的未来

Android 桌面化支持可以说是 Android 15 里被多次提及的 new features,例如在 Android 15 QPR1 Beta 2 里就提到为 Pixel 平板引入了桌面窗口支持,桌面窗口允许用户在自由窗口同时运行多个应用,同时可以像在传统 PC 平台上一样调整这些窗口的…

Vue+Vite 组件开发的环境准备(零基础搭建)

一、什么是Vite Vue3作为一款现代化的JavaScript框架,配合Vite这样的构建工具,极大地简化了流程,提升了效率。Vite 是一个基于现代浏览器原生的 ES 模块系统,能够以原生模块导入的方式运行源代码的开发服务器。它被设计用来替代传…

linux高级系统编程之进程

进程 一个正在进行的程序 并行与并发 并行:执行的程序在不同CPU上同时执行 并发:一个CPU,多个进程交替执行,因为交替速度很快,所以从宏观上来看是同时执行的,但是从围观的角度是交替执行的 单道与多道 单道程序设计:所有进程一个一个排队执行,若A阻塞,B只能等待,,即使CPU处于空…

git 命令之只提交文件的部分更改

git 命令之只提交文件的部分更改 有时,我们在一个文件中进行了多个更改,但只想提交其中的一部分更改。这时可以使用 使用 git add -p 命令 Git add -p命令允许我们选择并添加文件中的特定更改。它将会显示一个交互式界面,显示出文件中的每个更…

Excel中根据某列内容拆分为工作簿

简介:根据A列的内容进行筛选,将筛选出来的数据生成一个新的工作簿(可以放到指定文件夹下),且工作簿名为筛选内容。 举例: 将上面的内容使用VBA会在当前test1下生成5个工作簿,工作簿名分别为TEST1.xls TEST2.xls TEST3…

数据结构 (10)队列

前言 队列是一种特殊的数据结构,它遵循先进先出(FIFO,First In First Out)的原则。 一、定义与基本概念 定义:队列是一种只允许在一端(队尾)进行插入操作,而在另一端(队头…

Tomcat10部署Servlet加载错误问题解决

Servlet加载错误:HelloServlet不是Servlet 环境信息:IDEA中的maven项目,tomcat10.1.33 问题信息:XXX.Servlet不是Servlet 问题原因:tomcat10将JavaEE也换成了Jakarta EE; Jakarta EE较以前的JavaEE有一个重…

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

百度智能云发布首个空间智能解决方案,百度AI优势如何分析?

首先,百度智能云此次推出的空间智能解决方案,在技术底座上展现了其强大的AI异构计算能力。百度百舸AI异构计算平台作为该方案的底层支撑,为2D和3D应用中的人物、物件及场景生成提供了强大的算力支持。这一平台的推出,不仅提升了空…

RTSP摄像头、播放器为什么需要支持H.265?

H.264还是H.265? 好多开发者在做选RTSP播放器的时候,经常问我们的问题是,用H.264好还是H.265好?本文我们就H.264 和 H.265的主要区别和适用场景,做个大概的交流。 一、压缩效率 H.265 更高的压缩比 H.265 在相同视频…

BGP协议路由黑洞

一、实验环境 1、分公司与运营商AS自治系统内运行IGP路由协议OSPF、RIP或静态路由,AS自治系统内通过IBGP路由协议建立BGP邻居关系。 2、公司AS自治系统与运营商AS自治系统间运行EBGP路由协议。 3、通过loopback建立IBGP与EBGP邻居关系,发挥loopback建立…

解决数据传送问题:内网http传输

在服务器上启http服务 在服务器上输入命令: python3 -m http.server 1234 回车启动 访问和下载方法: 然后可以在本地的浏览器上访问:服务器IP:1234 例如192.11.1.1:1234,然后就可以下载对应文件夹下的东西了 在本地上启htt…

飞塔防火墙只允许国内IP访问

飞塔防火墙只允许国内IP访问 方法1 新增地址对象,注意里面已经细分为中国内地、中国香港、中国澳门和中国台湾 方法2 手动新增国内IP的对象组,目前好像一共有8632个,每个对象最多支持600个IP段

《Learn Three.js》学习(3)光源

前言: WebGL本身不支持光源,不使用three.js,则需使用着色程序来模拟光源。 学习大纲: Three.js中的光源 特定光源的使用时机 如何调整和配置所有光源的行为 如何创建镜头光晕 光源表 基础光源:THRER.AmbientLight、THERE.Point…

Linux——基础命令(2) 文件内容操作

目录 ​编辑 文件内容操作 1.Vim (1)移动光标 (2)复制 (3)剪切 (4)删除 (5)粘贴 (6)替换,撤销,查找 (7&#xff…

鸿蒙开发App 如何通过抓包查看 http 网络请求?

通过借助第三方工具 Charles https://www.charlesproxy.com/ https://www.zzzmode.com/mytools/charles/https://www.zzzmode.com/mytools/charles/ Charles 激活码计算器 相关博客日志:https://zhuanlan.zhihu.com/p/281126584 MAC上的使用方法: ch…

【Git】Git 完全指南:从入门到精通

Git 完全指南:从入门到精通 Git 是现代软件开发中最重要的版本控制工具之一,它帮助开发者高效地管理项目,支持分布式协作和版本控制。无论是个人项目还是团队开发,Git 都能提供强大的功能来跟踪、管理代码变更,并保障…

分布式锁的实现原理

作者:来自 vivo 互联网服务器团队- Xu Yaoming 介绍分布式锁的实现原理。 一、分布式锁概述 分布式锁,顾名思义,就是在分布式环境下使用的锁。众所周知,在并发编程中,我们经常需要借助并发控制工具,如 mu…

全新AI模型家族登场:完全可复现的开源语言模型OLMo 2

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…