行为型模式(一)策略模式

目录

[1. 介绍](#1. 介绍)

[2. 目的](#2. 目的)

[3. 实践](#3. 实践)


1. 介绍

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每种算法封装成具体的策略类,并使它们可以互相替换。策略模式使得算法可以独立于客户端而变化,客户端可以在运行时动态地选择不同的策略来执行相应的算法。

在策略模式中,通常包括以下几个角色:

  1. Context(上下文): 上下文类持有一个策略对象的引用,它将客户端请求委派给具体的策略对象来执行相应的算法。上下文类通常包含一个可以动态切换策略的方法,以便在运行时选择不同的策略。

  2. Strategy(策略): 策略接口或抽象类定义了一个算法族,其中每个具体的策略类实现了这个接口或继承了这个抽象类。策略类封装了具体的算法实现,客户端通过上下文类调用策略对象的方法来执行算法。

  3. ConcreteStrategy(具体策略): 具体策略类实现了策略接口或抽象类,它包含了具体的算法实现。每个具体策略类实现了一种特定的算法,可以根据具体需求选择不同的具体策略类来执行相应的算法。

策略模式的核心思想是将算法的实现和使用分离,使得算法可以独立变化而不影响客户端代码。通过策略模式,可以更好地组织和管理复杂的算法逻辑,提高代码的灵活性、可维护性和可扩展性。策略模式常用于需要动态地切换算法或根据不同条件选择不同算法的场景。

2. 目的

  • 消除大量的条件判断语句: 当代码中存在大量的if-else语句用于根据不同条件执行不同的逻辑时,策略模式可以帮助将不同的条件逻辑封装在不同的策略类中,从而避免代码臃肿和难以维护。

  • 提高代码的灵活性和可扩展性: 策略模式使得具体的策略类可以独立变化,客户端可以在运行时动态地选择不同的策略对象,从而实现系统的灵活性和可扩展性。

  • 避免代码重复: 将公共部分抽象到策略接口中,具体策略类只需实现自己特有的部分。

  • 提高代码的可读性和可维护性: 策略模式将算法的实现细节隐藏在具体策略类中,使得代码结构更清晰,易于理解和维护。

总的来说,策略模式可以帮助解决多个条件判断导致的代码复杂性、提高代码的灵活性和可扩展性,以及避免代码重复,从而提高代码质量和可维护性。

3. 实践

医嘱打印功能,多个打印模板,后续还会增加模板。

针对不同打印模板,进行不同数据处理。

使用策略模式就能很好解决此类问题。

java 复制代码
//策略接口
public interface IPrintMethod {

    List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO);

    default Map<String, List<BiOrderPrint>> toMap(List<BiOrderPrint> list) {
        return list.stream().collect(
                Collectors.groupingBy(BiOrderPrint::getFyFlag));
    }

    default List<BiOrderPrint> toList(Map<String, List<BiOrderPrint>> map) {
        return map.values().stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }
}

//策略实现类1
@Component
@RequiredArgsConstructor
public class PqMethod implements IPrintMethod {

    private final HandlerOne handlerOne;
    private final HandlerTwo handlerTwo;
    private final HandlerThree handlerThree;
    private final HandlerFour handlerFour;
    private final HandlerFive handlerFive;
    private final HandlerLast handlerLast;

    @Override
    public List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {
        //1. 数据转换,数据预处理
        List<BiOrderPrint> biOrderPrintList = handlerOne.doHandler(bo);
        Map<String, List<BiOrderPrint>> map1 = toMap(biOrderPrintList);
        //2. 数据填充
        Map<String, List<BiOrderPrint>> map2 = handlerTwo.doHandler(map1);
        //3. 根据每页条数,分割部分
        Map<String, List<BiOrderPrint>> map3 = handlerThree.doHandler(map2, dicItemDTO);
        //4. 每个分页里面的数据均是小于等于n的,将数据补 全
        Map<String, List<BiOrderPrint>> map4 = handlerFour.doHandler(map3, dicItemDTO);
        List<BiOrderPrint> resultList = toList(map4);
        // 5. 处理特殊数据
        handlerFive.doHandler(bo);
        // 6. 报存
        return handlerLast.doHandler(resultList);
    }
}

//策略实现类2
@Component
@RequiredArgsConstructor
public class SyMethod implements IPrintMethod {

    private final HandlerOne handlerOne;
    private final HandlerTwo handlerTwo;
    private final HandlerLast handlerLast;

    @Override
    public List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {
        // 1. 数据转换
        List<BiOrderPrint> biOrderPrintList = handlerOne.doHandler(bo);
        // 2. 过滤相同orderId的数据,只保留一份
        List<BiOrderPrint> list1 = new ArrayList<>(biOrderPrintList.stream()
                .collect(Collectors.toMap(BiOrderPrint::getOrderId,
                        Function.identity(),
                        (existing, replacement) -> existing))
                .values());
        // 3. 数据填充
        Map<String, List<BiOrderPrint>> map1 = toMap(list1);
        Map<String, List<BiOrderPrint>> map2 = handlerTwo.doHandler(map1);
        List<BiOrderPrint> resultList = toList(map2);
        // 4. 报存
        return handlerLast.doHandler(resultList);

    }
}

//......
//Context(上下文)
@Service
@RequiredArgsConstructor
public class OrderPrintContext {

    private final List<IPrintMethod> IPrintMethods;

    public List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {
        //将所有策略实现类放到map里,前端传具体策略
        Map<String, IPrintMethod> printMethodMap = IPrintMethods.stream().collect(Collectors
                .toMap(IPrintMethod -> IPrintMethod.getClass().getSimpleName(), Function.identity()));
        if (ObjectUtil.isNull(dicItemDTO)) {
            throw new ServiceException(OrderErrorEnum.ERROR_82003, bo.getBillType());
        }
        IPrintMethod IPrintMethod = printMethodMap.get(dicItemDTO.getValue3());
        return IPrintMethod.doPrint(bo, dicItemDTO);
    }
}
相关推荐
等一场春雨11 小时前
Java设计模式 九 桥接模式 (Bridge Pattern)
java·设计模式·桥接模式
等一场春雨14 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
小王子102417 小时前
设计模式Python版 单例模式
python·单例模式·设计模式
_DCG_17 小时前
c++常见设计模式之装饰器模式
c++·设计模式·装饰器模式
快乐非自愿17 小时前
「全网最细 + 实战源码案例」设计模式——单例设计模式
java·单例模式·设计模式
阿绵17 小时前
设计模式-模板方法实现
java·开发语言·设计模式
晚秋贰拾伍17 小时前
设计模式的艺术-职责链模式
运维·设计模式·运维开发·责任链模式·开闭原则·单一职责原则
博一波17 小时前
【设计模式-行为型】状态模式
设计模式·状态模式
w(゚Д゚)w吓洗宝宝了17 小时前
设计模式概述 - 设计模式的重要性
c++·设计模式
Cikiss17 小时前
「全网最细 + 实战源码案例」设计模式——工厂方法模式
java·后端·设计模式·工厂方法模式