Java设计模式:四、行为型模式-08:策略模式
文章目录
- 一、定义:策略模式
- 二、模拟场景:策略模式
- 三、违背方案:策略模式
- 3.0 引入依赖
- 3.1 工程结构
- 3.2 优惠券折扣计算类
- 3.3 单元测试
- 四、改善代码:策略模式
- 4.1 工程结构
- 4.2 策略模式结构图
- 4.3 优惠券折扣实现
- 4.3.1 定义优惠券接口
- 4.3.2 满减优惠券接口实现
- 4.3.3 直减优惠券接口实现
- 4.3.4 折扣优惠券接口实现
- 4.3.5 n元购优惠券接口实现
- 4.3.6 策略控制类
- 4.4 单元测试
- 4.4.1 直减券测试
- 4.4.2 满减券测试
- 4.4.3 折扣券测试
- 4.4.4 n元购测试
- 五、总结:策略模式
一、定义:策略模式

- 策略模式:是具有同类可替代的行为逻辑算法场景。比如:
- 不同类型的交易方式(信用卡、支付宝、微信)。
- 生成唯一
ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法)等。
二、模拟场景:策略模式

- 模拟在购买商品时使用的各种类型优惠券(满减、直减、折扣、m元)。
- 这个场景几乎也是大家的一个日常购物省钱渠道,购买商品的时候都希望找一些优惠券,让购买的商品更加实惠。而且到了大促的时候就会有更多的优惠券需要计算那些商品一起购买更加优惠。
- 这样的场景有时候用户用起来还是蛮爽的,但是最初这样功能的设定以及产品的不断迭代,对于程序员开发还是不容易的。
- 因为这里包括了很多的规则和优惠逻辑,所以我们模拟其中的一个计算优惠的方式,使用策略模式来实现。
三、违背方案:策略模式
📖 对于优惠券的设计最初可能非常简单,就是一个金额的折扣,也没有现在这么多种类型。
所以如果没有这样场景的经验,往往设计上也是非常简单的。
但随着产品功能的不断迭代,如果程序最初设计的不具备很好的扩展性,那么往后就会越来越混乱。
3.0 引入依赖
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency><!-- LOGGING begin --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.5</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>1.7.5</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.0.9</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency>
</dependencies>
3.1 工程结构
design-21.0-1
|——src|——main|--java|--com.lino.design|-CouponDiscountService.java|--test|--com.lino.design.test|-ApiTest.java
3.2 优惠券折扣计算类
CouponDiscountService.java
package com.lino.design;/*** @description: 优惠券折扣计算接口*/
public class CouponDiscountService {/*** 计算优惠券折扣** @param type 优惠券类型:1-直减券,2-满减券,3-折扣券,4-n元购* @param typeContent 折扣价格* @param skuPrice 商品价格* @param typeExt 满减价格* @return 折扣后的价格*/public double discountAmount(int type, double typeContent, double skuPrice, double typeExt) {// 1.直减券if (1 == type) {return skuPrice - typeContent;}// 2.满减券if (2 == type) {if (skuPrice < typeExt) {return skuPrice;}return skuPrice - typeContent;}// 3.折扣券if (3 == type) {return skuPrice * typeContent;}// 4.n元购if (4 == type) {return typeContent;}return 0D;}
}
- 以上是不同类型的优惠券计算折扣后的实际金额。
- 入参包括:优惠券类型、优惠券金额、商品金额、满减金额
- 因为有些优惠券是满多少减少多少,所以增加了
typeExt类型,这也是方法的不好扩展性问题。
- 因为有些优惠券是满多少减少多少,所以增加了
- 最后是整个方法体中对优惠券折扣金额的实现,最开始可能是一个最简单的优惠券,后面随着产品功能的增加,不断的扩展
if语句。
3.3 单元测试
ApiTest.java
package com.lino.design.test;import com.lino.design.CouponDiscountService;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @description: 单元测试*/
public class ApiTest {private Logger logger = LoggerFactory.getLogger(ApiTest.class);@Testpublic void test() {CouponDiscountService couponDiscountService = new CouponDiscountService();double result1 = couponDiscountService.discountAmount(1, 10D, 100D, 0D);logger.info("测试结果:直减优惠后金额:{}", result1);double result2 = couponDiscountService.discountAmount(2, 10D, 100D, 0D);logger.info("测试结果:满减优惠后金额:{}", result2);double result3 = couponDiscountService.discountAmount(3, 0.9D, 100D, 0D);logger.info("测试结果:折扣优惠后金额:{}", result3);double result4 = couponDiscountService.discountAmount(4, 90D, 100D, 0D);logger.info("测试结果:n元购金额:{}", result4);}
}
测试结果
17:05:07.040 [main] INFO com.lino.design.test.ApiTest - 测试结果:直减优惠后金额:90.0
17:05:07.049 [main] INFO com.lino.design.test.ApiTest - 测试结果:满减优惠后金额:90.0
17:05:07.049 [main] INFO com.lino.design.test.ApiTest - 测试结果:折扣优惠后金额:90.0
17:05:07.049 [main] INFO com.lino.design.test.ApiTest - 测试结果:n元购金额:90.0
四、改善代码:策略模式
💡 重构使用策略模式,优化代码结构,增强整体的扩展性。
4.1 工程结构
design-21.0-2
|——src|——main|--java|--com.lino.design|--impl| |--MJCouponDiscount.java| |--NYGCouponDiscount.java| |--ZJCouponDiscount.java| |--ZKCouponDiscount.java|-Context.java|-ICouponDiscount.java|--test|--com.lino.design.test|-ApiTest.java
4.2 策略模式结构图

- 整体的结构模式并不复杂,主要体现的不同类型的优惠券在计算优惠券方式的不同计算策略。
- 这里包括一个接口类(
ICouponDiscount),以及四种优惠券类型的实现方式。 - 最后提供了策略模式的上下控制类处理,整体的策略服务。
4.3 优惠券折扣实现
4.3.1 定义优惠券接口
ICouponDiscount.java
package com.lino.design;import java.math.BigDecimal;/*** @description: 优惠券折扣计算接口*/
public interface ICouponDiscount<T> {/*** 计算优惠券折扣** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠券折扣后的价格*/BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);
}
- 定义了优惠券折扣接口,也增加了泛型用于不同类型的接口可以传递不同的类型参数。
- 接口中包括商品金额以及出参返回最终折扣后的金额。
4.3.2 满减优惠券接口实现
MJCouponDiscount.java
package com.lino.design.impl;import com.lino.design.ICouponDiscount;
import java.math.BigDecimal;
import java.util.Map;/*** @description: 满减券*/
public class MJCouponDiscount implements ICouponDiscount<Map<String, String>> {/*** 满减计算* 1.判断满足x元后-n元,否则不减* 2.最低 支付金额1元** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠后价格*/@Overridepublic BigDecimal discountAmount(Map<String, String> couponInfo, BigDecimal skuPrice) {String x = couponInfo.get("x");String n = couponInfo.get("n");// 小于商品金额条件的,直接返回商品原价if (skuPrice.compareTo(new BigDecimal(x)) < 0) {return skuPrice;}// 减去优惠金额判断BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(n));if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {return BigDecimal.ONE;}return discountAmount;}
}
4.3.3 直减优惠券接口实现
ZJCouponDiscount.java
package com.lino.design.impl;import com.lino.design.ICouponDiscount;
import java.math.BigDecimal;/*** @description: 直减券*/
public class ZJCouponDiscount implements ICouponDiscount<Double> {/*** 直减计算* 1.使用商品价格减去优惠价格* 2.最低支付金额1元** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠后价格*/@Overridepublic BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(couponInfo));if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {return BigDecimal.ONE;}return discountAmount;}
}
4.3.4 折扣优惠券接口实现
ZKCouponDiscount.java
package com.lino.design.impl;import com.lino.design.ICouponDiscount;
import java.math.BigDecimal;/*** @description: 折扣券*/
public class ZKCouponDiscount implements ICouponDiscount<Double> {/*** 折扣计算* 1.使用商品价格乘以折扣比例,为最后支付金额* 2.保留两位小数* 3.最低支付金额1元** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠后价格*/@Overridepublic BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {BigDecimal discountAmount = skuPrice.multiply(new BigDecimal(couponInfo)).setScale(2, BigDecimal.ROUND_HALF_UP);if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {return BigDecimal.ONE;}return discountAmount;}
}
4.3.5 n元购优惠券接口实现
NYGCouponDiscount.java
package com.lino.design.impl;import com.lino.design.ICouponDiscount;
import java.math.BigDecimal;
import java.util.Map;/*** @description: n元购*/
public class NYGCouponDiscount implements ICouponDiscount<Double> {/*** n元购* 1.无论原价多少钱都固定金额购买** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠后价格*/@Overridepublic BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {return new BigDecimal(couponInfo);}
}
4.3.6 策略控制类
Context.java
package com.lino.design;import java.math.BigDecimal;/*** @description: 策略控制类*/
public class Context<T> {private ICouponDiscount<T> couponDiscount;public Context(ICouponDiscount<T> couponDiscount) {this.couponDiscount = couponDiscount;}/*** 计算优惠券折扣** @param couponInfo 优惠券信息泛型* @param skuPrice 商品价格* @return 优惠券折扣后的价格*/public BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice) {return couponDiscount.discountAmount(couponInfo, skuPrice);}
}
- 策略模式的控制类主要是外部可以传递不同的策略实现,再通过统一的方法执行优惠策略计算。
- 另外这里也可以包装出
map结构,让外部只需要对应的泛型类型即可使用相应的服务。
4.4 单元测试
4.4.1 直减券测试
ApiTest.java
@Test
public void test_zj() {Context<Double> context = new Context<>(new ZJCouponDiscount());BigDecimal discountAmount = context.discountAmount(10D, new BigDecimal(100));logger.info("测试结果:直减优惠后金额:{}", discountAmount);
}
测试结果
17:16:00.390 [main] INFO com.lino.design.test.ApiTest - 测试结果:直减优惠后金额:90
4.4.2 满减券测试
ApiTest.java
@Test
public void test_mj() {Context<Map<String, String>> context = new Context<>(new MJCouponDiscount());Map<String, String> mapReq = new HashMap<>();mapReq.put("x", "100");mapReq.put("n", "10");BigDecimal discountAmount = context.discountAmount(mapReq, new BigDecimal(100));logger.info("测试结果:满减优惠后金额:{}", discountAmount);
}
测试结果
17:16:35.300 [main] INFO com.lino.design.test.ApiTest - 测试结果:满减优惠后金额:90
4.4.3 折扣券测试
ApiTest.java
@Test
public void test_zk() {Context<Double> context = new Context<>(new ZKCouponDiscount());BigDecimal discountAmount = context.discountAmount(0.9D, new BigDecimal(100));logger.info("测试结果:折扣9折后金额:{}", discountAmount);
}
测试结果
17:17:06.907 [main] INFO com.lino.design.test.ApiTest - 测试结果:折扣9折后金额:90.00
4.4.4 n元购测试
ApiTest.java
@Test
public void test_nyg() {Context<Double> context = new Context<>(new NYGCouponDiscount());BigDecimal discountAmount = context.discountAmount(90D, new BigDecimal(100));logger.info("测试结果:n元购优惠后金额:{}", discountAmount);
}
测试结果
17:17:35.616 [main] INFO com.lino.design.test.ApiTest - 测试结果:n元购优惠后金额:90
💡 以上四个测试分别验证了不同类型优惠券的优惠策略,测试结果是满足我们的预期。
这里四种优惠券最终都是再原价100元上折扣10元,最终支付90元。
五、总结:策略模式
- 策略模式案例相对来说并不复杂,主要的逻辑都是体现在关于不同类型优惠券的计算折扣策略上。
- 结构相对来说也比较简单,在实际的开发中这样的设计模式也是非常常用的。
- 另外策略模式与命令模式、适配器模式结构相似,但是思路是有差异的。
- 通过策略模式的使用可以把我们方法中的
if语句优化掉,大量的if语句使用会让代码难为扩展,也不好维护,同时在后期遇到各种问题也很难维护。 - 在使用策略模式可以很好的满足隔离性和扩展性,对于不断新增的需求也非常方便承接。
策略模式、适配器模式、组合模式等,在一些结构上是比较相似的。但是每一个模式都有自己的逻辑特点,在使用的过程中最佳的方式是经过较多的实践来吸取经验,为后续的研发设计提供更好的技术输出。
相关文章:
Java设计模式:四、行为型模式-08:策略模式
文章目录 一、定义:策略模式二、模拟场景:策略模式三、违背方案:策略模式3.0 引入依赖3.1 工程结构3.2 优惠券折扣计算类3.3 单元测试 四、改善代码:策略模式4.1 工程结构4.2 策略模式结构图4.3 优惠券折扣实现4.3.1 定义优惠券接…...
ICCOA蓝牙数字车钥匙2.0
近期,ICCOA智慧车联开放联盟宣布,由小米、vivo、OPPO、长安、深蓝、吉利、极氪、比亚迪、北汽、蔚来、零跑、雪球、瓶钵、融卡等企业联合参与制定的ICCOA蓝牙数字车钥匙2.0标准(简称DK2.0),于2023年9月1日正式发布实施…...
ArcGIS土地利用程度综合指数分析
成图展示: 土地利用程度综合指数 第一步 准备数据 使用的数据为2010年河南省土地利用类型数据与其行政区划县级数据(为了节省操作,这里使用上次实验的部分数据[1],各土地利用类型已被提取) 第二步 面积统计 水域为例…...
服务端请求伪造(SSRF)及漏洞复现
文章目录 渗透测试漏洞原理服务端请求伪造1. SSRF 概述1.1 SSRF 场景1.1.1 PHP 实现 1.2 SSRF 原理1.3 SSRF 危害 2. SSRF 攻防2.1 SSRF 利用2.1.1 文件访问2.1.2 端口扫描2.1.3 读取本地文件2.1.4 内网应用指纹识别2.1.5 攻击内网Web应用 2.2 SSRF 经典案例2.2.1 访问页面2.2.…...
v-model和v-bind
v-model,它其实就是一个语法糖,作用就是双向绑定表单控件(radio, text,address,email,select,checkbox,textarea) v-bind(简写形式:value值),用于绑定属性值,只能实现数据的单项绑定。 <template> <div>…...
详细介绍 弹性盒子(display:flex)
文章目录 什么是弹性盒子 如何使用弹性盒子flex系列flex-direction 对齐方向 水平对齐垂直对齐flex-wrap 换行flex-flowflex模型说明容器的属性 justify-content X轴对齐方式align-content Y轴对齐方式总结属性值Y轴对齐的另外一种:align-itemsalign-content和alig…...
Docker使用数据卷挂载进行数据存储与共享
一、挂载和数据卷 在 Docker 中,挂载(Mounting)和数据卷(Data Volumes)是用于在容器和宿主机之间共享数据的机制。 挂载:将宿主机文件系统中的目录或文件与容器中的目录或文件进行关联的过程。数据卷&…...
[力扣146. LRU 缓存 ](https://leetcode.cn/problems/lru-cache/description/)
力扣146. LRU 缓存 使用LinkedHashmap(HashMap的子类,能够记住插入数据的顺序). LRU是Lease Recently User的缩写,意思是最近 最少使用。比如设计一个文件缓存系统,每个文件有自己的大小和访问时间,文件缓存系统有总的大小&…...
Mysql存储引擎
目录 一、前言 二、存储引擎 1、InnoDB存储引擎 1.1、简介 1.2、优势 1.3、使用方法 1.4、性能 2、MyISAM存储引擎 2.1、优势 2.2、使用方法 2.3、性能 3、MEMORY存储引擎 4、MyISAM 三、比较 四、总结 一、前言 MySQL是开放源代码的关系型数据库管理系统&…...
算法通关村-----数组实现加法专题问题解析
数组实现整数加法 问题描述 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。详见leetcode66 问题…...
倒排表的压缩算法
For压缩算法 这是倒排表的一种压缩算法。 还是那个问题,如果"小米" 这个词项,在多文档里都有,则就会导致倒排表很大,这时候就会设计到了压缩算法,这里说的是,倒排表。 那末我们来看看 for压缩…...
Android studio实现自定义圆形进度条 带刻度进度条 计步效果 时速表 水波纹效果
目录 原文链接效果图values /layout /activity原文链接 效果图 点击重置后: 该项目总共实现了三种圆形进度条效果 CircleProgress:圆形进度条,可以实现仿 QQ 健康计步器的效果,支持配置进度条背景色、宽度、起始角度,支持进度条渐变DialProgress:类似 CircleProgress,…...
使用【宝塔+docker】在云服务器上部署基于SpringBoot 和 Dubbo RPC 的项目:踩坑记录
待部署的项目包括:前端front,服务提供者backend,服务消费者gateway,注册中心nacos 服务器信息:腾讯云入门级服务器2核2G(后续有对服务器进行升级) 部署工具:前端使用宝塔部署&#x…...
【算法与数据结构】617、LeetCode合并二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:采用递归的方式遍历二叉树,【算法与数据结构】144、94、145LeetCode二叉树的前中后遍历&am…...
ffmpeg把RTSP流分段录制成MP4,如果能把ffmpeg.exe改成ffmpeg.dll用,那音视频开发的难度直接就降一个维度啊
比如,原来我们要用ffmpeg录一段RTSP视频流转成MP4,我们有两种方案: 方案一:可以使用以下命令将rtsp流分段存储为mp4文件 ffmpeg -i rtsp://example.com/stream -vcodec copy -acodec aac -f segment -segment_time 3600 -reset_t…...
朝夕光年游戏自动化测试实践
朝夕光年是面向全球用户与开发者的游戏研发与发行业务品牌,致力于服务全球玩家,帮助玩家在令人惊叹的虚拟世界中一起玩耍与创造。 在游戏的研发过程中,游戏自动化一直是开展难度较大的工程,具体包括机房机架、设备调度、软件框架、…...
数据结构基本概念
一、数据 数据对象-数据元素-数据项(属性),前者由后者组成 二、数据结构 定义:按某种关系的数据元素的集合 三、数据类型 1、原子类型(例如整型) 2、结构类型(由原子类型组成,例如数组) 3、…...
【javaweb】学习日记Day9 - Mybatis 基础操作
目录 一、删除 (1)在mapper接口执行sql删除语句 ① 注解后sql语句没有提示怎么办? (2)测试层 (3)开启mybatis日志 (4)预编译SQL 二、新增 (1&#…...
Mybatis学习|Mybatis缓存:一级缓存、二级缓存
Mybatis缓存 MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地…...
230903文本docx
处理文本 块级项目,每次文本超出右边界时都会添加一行.对段落,边界一般是页边距,但如果按列布局页,则也可是列边界,如果表格单元格内有段,则也可是单元格边界. 块级项属性指定其在页上的位置,如缩进项及段落前后间距.内联项属性一般指定显示内容的如字样,字体大小,粗体和斜体…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
