策略模式-实践

这篇具有很好参考价值的文章主要介绍了策略模式-实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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


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

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

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

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

  // Helper method to update card data based on tag
    private static void updateCardData(String tagName, byte [] data, Card card) {
        // Update card data based on the tag
        Logs.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 length
                byte[] tagBytes = Arrays.copyOfRange(data, 2, 2 + data[1] & 0xFF);
                String tagString = tools.hexString(tagBytes);
                System.out.println(tagString);
                card.setPan(tagString);
                break;
            case epanSeqNo:
                // 解析Tag
                int tag = data[0] & 0xFF;
                // 解析Length
                int 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 {
    @Override
    public 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 found
        if (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 needed
                break;
        }
        return card;
    }

    // 处理卡号数据
    static private String processCardNumber(byte[] cardNumberData) {
        // 在此处实现卡号数据的处理逻辑,例如格式化和解析
        // 返回处理后的卡号字符串
        return new String(cardNumberData);
    }
}

策略模式-实践,策略模式,java文章来源地址https://www.toymoban.com/news/detail-790831.html

到了这里,关于策略模式-实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java设计模式---策略模式

    策略设计模式是一种行为设计模式。当在处理一个业务时,有多种处理方式,并且需要再运行时决定使哪一种具体实现时,就会使用策略模式。 策略模式的类图: 在支付业务中,有三种付款方式,程序运行时使用哪种方式由用户选择,根据用户选择执行不同的逻辑。 首先,

    2024年02月10日
    浏览(23)
  • Java特性之设计模式【策略模式】

    概述 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法 主要解决 :在有多种

    2024年02月08日
    浏览(28)
  • Java设计模式之策略模式详解

    大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,让我们一同踏入Java设计模式之策略模式的世界,探讨代码中的智慧抉择。 策略模式的核心思想 策略模式是一种行为型设计模式,它定义了算法家族

    2024年01月20日
    浏览(21)
  • Java设计模式之策略(Strategy)模式

    策略(Strategy)设计模式定义了一系列算法,将它们封装起来,并且可以相互替换使用,从而使得算法可以独立于使用它的客户而变化。 策略(Strategy)设计模式是一种行为型设计模式,它允许在运行时动态地选择算法。策略模式将算法封装为算法族,从而可以在运行时根据

    2024年02月15日
    浏览(20)
  • java 策略模式

    策略模式(Strategy Pattern) 指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。将每个算法封装在独立的类中,使得它们可以互相替换。可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。 主要解决: 在有多种算法相似的情况下,使用 if..

    2024年04月15日
    浏览(8)
  • java策略模式简单分析

    欢迎来到本博客,今天我们将深入探讨Java中的策略模式。策略模式是一种行为设计模式,它允许你定义一系列算法,并将每个算法封装起来,使它们可以相互替换,而且可以独立于客户端使用。 策略模式是一种定义一系列算法的方法,从概念上来看,所有的这些算法完成的

    2024年01月25日
    浏览(12)
  • java策略模式

    在Java中,策略模式(Strategy Design Pattern)用于定义一系列算法,并将每个算法封装成单独的类,使得它们可以互相替换,让客户端在使用算法时不需要知道具体的实现细节。策略模式是一种行为型设计模式,它允许客户端选择要使用的算法,而无需修改客户端代码。 策略模式

    2024年02月15日
    浏览(9)
  • Java设计模式——策略

    前言 策略模式是平时Java开发中常用的一种,虽然已有很多讲解设计模式的文章,但是这里还是写篇文章来从自己理解的角度讲解一下。 我们不妨进行场景假设,要对我们的软件进行授权管理:在启动我们的软件之前先要校验是否存在合法的授权,如果授权不合法则要求用户

    2024年02月20日
    浏览(23)
  • Java设计模式-策略模式-基于Spring实现

    策略模式是一种行为设计模式,它允许在运行时选择算法的行为。它将算法封装在 独立的策略类 中,使得它们可以相互替换,而不影响客户端代码。这种模式通过 将算法的选择从客户端代码中分离出来 ,提供了更大的灵活性和可维护性。 在Java中,策略模式的设计理念可以

    2024年02月08日
    浏览(27)
  • Java设计模式—策略模式(Strategy Mode)

    目录 前言 一、策略模式的简介 二、策略模式的概念 三、策略模式的作用 四、策略模式的优、缺点 策略模式的优点: 策略模式的缺点: 五、策略模式应用场景 六、代码案例 1)抽象接口类 2)具体的策略类:减 3)具体策略类:打折 4)上下文类 5)客户端Main代码测试 总结

    2024年02月08日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包