策略模式-实践

俗话说:条条大路通罗马。在很多情况下,实现某个目标的途径不止一条,例如我们在外出
旅游时可以选择多种不同的出行方式,如骑自行车、坐汽车、坐火车或者坐飞机,可根据实
际情况(目的地、旅游预算、旅游时间等)来选择一种最适合的出行方式。在制订旅行计划
时,如果目的地较远、时间不多,但不差钱,可以选择坐飞机去旅游;如果目的地虽远、但
假期长、且需控制旅游成本时可以选择坐火车或汽车;如果从健康和环保的角度考虑,而且
有足够的毅力,自行车游或者徒步旅游也是个不错的选择。


在软件开发中,我们也常常会遇到类似的情况,实现某一个功能有多条途径,每一条途径对
应一种算法,此时我们可以使用一种设计模式来实现灵活地选择解决途径,也能够方便地增
加新的解决途径。本章我们将介绍一种为了适应算法灵活性而产生的设计模式——策略模
式。

(1) MovieTicket类的calculate()方法非常庞大,它包含各种打折算法的实现代码,在代码中出现
了较长的if…else…语句,不利于测试和维护。
(2) 增加新的打折算法或者对原有打折算法进行修改时必须修改MovieTicket类的源代码,违反
了“开闭原则”,系统的灵活性和可扩展性较差。
(3) 算法的复用性差,如果在另一个系统(如商场销售管理系统)中需要重用某些打折算法,
只能通过对源代码进行复制粘贴来重用,无法单独重用其中的某个或某些算法(重用较为麻
烦)。

如何解决这三个问题?导致产生这些问题的主要原因在于MovieTicket类职责过重,它将各种
打折算法都定义在一个类中,这既不便于算法的重用,也不便于算法的扩展。因此我们需要
对MovieTicket类进行重构,将原本庞大的MovieTicket类的职责进行分解,将算法的定义和使
用分离,这就是策略模式所要解决的问题,下面将进入策略模式的学习。

策略模式
符合"依赖倒转原则"
策略模式Strategy Pattern:定义一系列算法类,
将每一个算法封装起来,并让他们可以相互替换,
策略模式让算法独立于使用它的客户而变化。
策略模式的主要目的是将算法的定义与使用分开。

  // Helper method to update card data based on tagprivate static void updateCardData(String tagName, byte [] data, Card card) {// Update card data based on the tagLogs.d(TAG,"dataOut.length: "+data.length);String ordata =  tools.hexString(data);Logs.d(TAG,tagName + "原始数据 "+ ordata);switch (tagName) {case eICCardNumber:// Skip the first two bytes, the first one is the tag, and the second is the lengthbyte[] tagBytes = Arrays.copyOfRange(data, 2, 2 + data[1] & 0xFF);String tagString = tools.hexString(tagBytes);System.out.println(tagString);card.setPan(tagString);break;case epanSeqNo:// 解析Tagint tag = data[0] & 0xFF;// 解析Lengthint length = data[1] & 0xFF;// 获取PAN Sequence Number的值byte panSequenceNumber = data[2];System.out.println("Tag: " + Integer.toHexString(tag));System.out.println("Length: " + length);System.out.println("PAN Sequence Number: " + panSequenceNumber);card.setPanSeqNo((int)panSequenceNumber);break;case ecardHolderName:byte[] cardHolderName = Arrays.copyOfRange(data, 3, 3 + data[2] & 0xFF);String resultString = new String(cardHolderName, StandardCharsets.UTF_8);System.out.println(resultString);System.out.println("ecardHolderName: " + resultString);card.setCardHolderName(resultString);break;case eserviceCode:byte[] serviceCode = Arrays.copyOfRange(data, 3, 3 + data[2] & 0xFF);String sserviceCode = tools.hexString(serviceCode);card.setServiceCode(sserviceCode);break;case eissuerCountryCode:byte[] issuerCountryCode = Arrays.copyOfRange(data, 3, 3 + data[2] & 0xFF);String ssuerCountryCode = tools.hexString(issuerCountryCode);Log.d(TAG,"ssuerCountryCode"+ ssuerCountryCode);int CountryCode = Integer.parseInt(ssuerCountryCode, 10);Log.d(TAG,"CountryCode"+ CountryCode);card.setIssuerCountryCode(CountryCode);break;case elabel:byte[] label = Arrays.copyOfRange(data, 2, 2 + data[1] & 0xFF);String slabel = new String(label, StandardCharsets.UTF_8);System.out.println(slabel);card.setLabel(slabel);break;case ecardExpirationDate:byte[] cardExpirationDate = Arrays.copyOfRange(data, 3, 3 + data[2] & 0xFF);String scardExpirationDate = tools.hexString(cardExpirationDate);Log.d(TAG,"scardExpirationDate"+ scardExpirationDate);Date parsedDate = null;    SimpleDateFormat sdf = new SimpleDateFormat("MMddyy");try {parsedDate = sdf.parse(scardExpirationDate);} catch (ParseException e) {e.printStackTrace();}card.setCardExpirationDate(parsedDate);break;default:break;}}

使用策略模式修改后的代码

public interface CardDataUpdateStrategy {void updateCardData(byte[] data, Card card);
}
public class LabelStrategy implements CardDataUpdateStrategy {@Overridepublic void updateCardData(byte[] data, Card card) {byte[] label = Arrays.copyOfRange(data, 2, 2 + data[1] & 0xFF);String slabel = new String(label, StandardCharsets.UTF_8);System.out.println(slabel);card.setLabel(slabel);}
}public class ICCData {private static final String TAG = ICCData.class.getSimpleName();static  Card card;static final private  int expectDataLen = 20;  // 期望TLV返回的长度static final String eICCardNumber ="ICCardNumber";static final String epanSeqNo ="panSeqNo";static final String ecardHolderName ="cardHolderName";static final String eserviceCode ="serviceCode";static final String eissuerCountryCode ="issuerCountryCode";static final String elabel ="label";static final String ecardExpirationDate ="cardExpirationDate";private static final Map<String, CardDataUpdateStrategy> strategyMap;static {strategyMap = new HashMap<>();strategyMap.put(eICCardNumber, new PANUpdateStrategy());strategyMap.put(epanSeqNo, new PanSeqNoUpdateStrategy());strategyMap.put(ecardHolderName, new CardHolderNameStrategy());strategyMap.put(eserviceCode, new ServiceCodeStrategy());strategyMap.put(eissuerCountryCode, new IssuerCountryCodeStrategy());strategyMap.put(elabel, new LabelStrategy());strategyMap.put(ecardExpirationDate, new ExpirationDateStrategy());}// 获取 Card 实例的方法public static Card getCardInstance() {if (card == null) {card = new Card();}return card;}private static void updateCardData(TagInfo tagInfo, Card card) {String ordata = tools.hexString(tagInfo.tag);Logs.d(TAG, tagInfo.getTagName() + "原始数据 " + ordata);CardDataUpdateStrategy strategy = strategyMap.get(tagInfo.getTagName());// Check if a valid strategy is foundif (strategy != null) {strategy.updateCardData(tagInfo.getTag(), card);}}public static Card getICCardNumber() {List<TagInfo> tagInfoList = Arrays.asList(new TagInfo(new byte[]{(byte) 0x5A}, eICCardNumber),new TagInfo(new byte[]{(byte) 0x5F, (byte) 0x34}, epanSeqNo),new TagInfo(new byte[]{(byte) 0x5F, (byte) 0x20}, ecardHolderName),new TagInfo(new byte[]{(byte) 0x5F, (byte) 0x30}, eserviceCode),new TagInfo(new byte[]{(byte) 0x5F, (byte) 0x28}, eissuerCountryCode),new TagInfo(new byte[]{(byte) 0x50}, elabel),new TagInfo(new byte[]{(byte) 0x5F, (byte) 0x24}, ecardExpirationDate));Card card = getCardInstance();for (TagInfo tagInfo : tagInfoList) {getICCardData(tagInfo, card);}card.setType(ICC);return card;}public static Card getICCardData(TagInfo tagInfo, Card card) {ByteArray dataOut = new ByteArray(expectDataLen);int result = EMV_GetTLVDataList(tagInfo.tag, (byte) tagInfo.tag.length, expectDataLen, dataOut);switch (result) {case EMV_OK:tagInfo.tag = Arrays.copyOfRange(dataOut.data, 0, dataOut.length);updateCardData(tagInfo, card);break;case EMV_PARAM_ERR:System.out.println("Error: Parameters error (null pointer).");break;case EMV_DATA_ERR:System.out.println("Error: Data error, illegal tags.");break;case EMV_NO_DATA:System.out.println("Error: The tag is not present.");break;case EMV_OVERFLOW:System.out.println("Warning: Data overflow. Actual data cut off to the length of expectDataLen.");break;default:// Handle other return codes as neededbreak;}return card;}// 处理卡号数据static private String processCardNumber(byte[] cardNumberData) {// 在此处实现卡号数据的处理逻辑,例如格式化和解析// 返回处理后的卡号字符串return new String(cardNumberData);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星河璀璨:飞桨星河文心SDK与Gurdance珠联璧合让大模型更像人!

星河璀璨&#xff1a;飞桨星河文心SDK与Gurdance珠联璧合让大模型更像人&#xff01; 本项目效果惊艳&#xff0c;可以在AIStudio星河社区一键运行 只需要在cpu基础版下运行&#xff0c;妈妈再也不怕我的算力不够了&#xff01; 1、引言 2023年8月22日&#xff0c;百度董事…

3.14.1 函数对象 Page139~141

28行&#xff0c;doggie是一个类型为Dog的对象&#xff0c;而“()”是它的一个成员函数&#xff0c;doggie()实际上是doggie.operator() "operator()"既然是函数&#xff0c;那就可以有参数&#xff0c;也可以有返回值 运行结果为&#xff1a;

新微信公众号没有留言功能, 你们怎么破?

为什么公众号没有留言功能&#xff1f;从2018年2月开始&#xff0c;新注册的微信公众号取消了留言功能&#xff0c;原因是为了规避一些营销号通过虚假留言骗取读者信任。不过大部分公众号运营者对TX此举感到失望&#xff0c;一方面大片的留言就像店前排队的顾客&#xff0c;能体…

PLC、工业设备如何远程访问?贝锐蒲公英云智慧组网实现数据互通

在工业4.0时代&#xff0c;工业数字化的核心在于数据的互联互通&#xff0c;而在整个工业数字化、智能化的过程中&#xff0c;往往面临数据采集困难、设备运行情况难以知晓、部署管理难度大、后期维护成本高等问题。 显然&#xff0c;PLC设备在整个工业数字化进程中扮演的角色…

freertos任务管理器,任务监控

freertos提供了类似于windows的任务管理器功能&#xff0c;具体地如下&#xff1a; 1、configUSE_TRACE_FACILITY 和 configUSE_TRACE_FACILITY使能置1 2、调用vTaskList&#xff0c;如下&#xff1a; if(idleTaskCounter%84){char printlist[2048];vTaskList(printlist);Prin…

ssm基于Java的药店药品信息管理系统的设计与实现论文

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;药品信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广大…

11-适配器模式(Adapter)

意图 将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。 适配器模式属于结构模式。 类适配器模式&#xff08;通过继承的方式实现适配器模式&#xff09; Adapter类&#xff0c;通过继承src类&#xff0…

vulnhub靶场之DC-8

一.环境搭建 1.靶场描述 DC-8 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing. This challenge is a bit of a hybrid between being an actual challenge, and being a "proof of concept&quo…

【技术选型】Doris vs starRocks

比对结论 仅从当前能看到的数据中&#xff0c;相比于doris&#xff0c;starRocks在性能方面具备优势&#xff0c;且更新频率高&#xff08;降低维护成本&#xff09;。 目标诉求 并发性不能太低——相比于clickhouse不到100的QPS支持大表关联——降低数据清洗的压力&#xf…

家用洗地机哪个品牌质量比较好?高配置洗地机推荐

近年来&#xff0c;科技飞速发展&#xff0c;推动了多个新兴行业的崛起&#xff0c;其中洗地机行业也在不断扩大。然而&#xff0c;随着市场的蓬勃发展&#xff0c;洗地机市场的产品质量参差不齐。在众多品牌中&#xff0c;真正致力于深入研究和创新的品牌相对较少。洗地机的问…

电流检测方法

电路检测电路常用于&#xff1a;高压短路保护、电机控制、DC/DC换流器、系统功耗管理、二次电池的电流管理、蓄电池管理等电流检测等场景。 对于大部分应用&#xff0c;都是通过感测电阻两端的压降测量电流。 一般使用电流通过时的压降为数十mV&#xff5e;数百mV的电阻值&…

VUE element-ui实现表格动态展示、动态删减列、动态排序、动态搜索条件配置、表单组件化。

1、实现效果 1.1、文件目录 1.2、说明 1、本组件支持列表的表头自定义配置&#xff0c;checkbox实现 2、本组件支持列表列排序&#xff0c;vuedraggable是拖拽插件&#xff0c;上图中字段管理里的拖拽效果 &#xff0c;需要的话请自行npm install 3、本组件支持查询条件动态…

将Android应用修改为鸿蒙应用的工作

将Android应用修改为鸿蒙&#xff08;HarmonyOS&#xff09;应用需要进行一系列主要的工作。以下是在进行这一转换过程中可能需要进行的主要工作&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.项目…

Microsoft Excel 直方图

Microsoft Excel 直方图 1. 数据示例2. 打开 EXCEL3. settings4. 单击直方图柱&#xff0c;右键“添加数据标签”References 1. 数据示例 2. 打开 EXCEL 数据 -> 数据分析 -> 直方图 3. settings 输入区域样本值、接受区域分类间距&#xff0c;输出选项选择“新工作表组…

手把手图解教你Java SPI源码分析

原创/朱季谦 我在《Java SPI机制总结系列之开发入门实例》一文当中&#xff0c;分享了Java SPI的玩法&#xff0c;但是这只是基于表面的应用。若要明白其中的原理实现&#xff0c;还需深入到底层源码&#xff0c;分析一番。 这里再重温一下SPI机制的概念&#xff1a;SPI&#…

JS实现网页轮播图

轮播图也称为焦点图&#xff0c;是网页中比较常见的网页特效。 1、页面基本结构&#xff1a; 大盒子focus&#xff0c;里面包含 左右按钮ul 包含很多个li &#xff08;每个li里面包含了图片&#xff09;下面有很多个小圆圈 因为我们想要点击按钮&#xff0c;轮播图左右播放&a…

外部晶振、复位按键、唤醒按键、扩展排针原理图详解

前言&#xff1a;本文对外部晶振、复位按键、唤醒按键、扩展排针原理图详解。本文使用的MCU是GD32F103C8T6 目录 外部晶振原理图 复位按键、唤醒按键原理图 扩展排针部分原理图 ​外部晶振原理图 如下图&#xff0c;两个外部晶振&#xff0c;分别是8M&#xff08;主晶振&a…

【InternLM 大模型实战】第三课

基于 InternLM 和 LangChain 搭建你的知识库 大模型开发范式RAG&#xff08;检索增强生成&#xff09;FINETUNE&#xff08;微调&#xff09; LangChain 简介构建向量数据库加载源文件文档分块文档向量化 搭建知识库助手构建检索问答链RAG方案优化建议 Web Demo 部署动手实战In…

让网页自动化测试更简便,流程图设计工具为您解决痛点

在数字化时代&#xff0c;网页自动化测试已经成为提高工作效率、保证项目质量的重要手段。然而&#xff0c;传统的自动化测试往往需要复杂的编程技能&#xff0c;对非专业人员来说门槛较高。为了解决这个问题&#xff0c;我们向您推荐一款创新的设计工具&#xff0c;它可以通过…

使用numpy处理图片——二值图像

大纲 载入图像灰阶处理二值处理 在《使用numpy处理图片——灰阶影像》一文中&#xff0c;我们将彩色图片转换成灰阶图片。本文将在这个基础上将灰阶图片转换成二值图像。 二值图像就是只有黑白两种颜色的图像。像素最终显示黑还是白&#xff0c;需要有一个判断标准。如果图片太…