java - 使用 java 8 的设计模式建议/实现

标签 java algorithm spring-boot design-patterns java-8

我必须通过一系列步骤处理请求。

例如:如果请求 1 到来,那么我必须应用步骤 1、步骤 2、步骤 3,最后应用步骤 4,这会将处理后的请求保存到数据库中。

我考虑实现模板设计模式,因为它解决了类似的问题。

当我开始实现设计模式时,我突然发现它很难实现,因为逻辑复杂。

让我解释一下要求:

请求 -> Controller -> run()

请求将包含 List<objects> .
run方法中,将触发一系列操作。

request.parallelStream()
    .map(step1 -> executeStep1.apply(step1))
    .map(step2 -> executeStep2.apply(step2, action))
    .map(step3 -> executeStep3.apply(step3, rules))
    .map(step4 -> executeStep4.apply(step4))
    .collect(Collectors.toList());

    Function<String, List<PersonDto>> executeStep1= person-> {
        return metaData.getMetaDataPerson(person);
    };

    BiFunction<List<PersonDto>, String, TransTemplateDTO> executeStep2= (metaData, action) -> {
        return temlate.createTemplate(metaData, action);
    };

现在,正如我们所看到的,我正在传递 request 的第一个元素作为step1()的输入,然后对其进行处理,并进一步将输出作为输入传递给后续步骤。

  • 问题 1:
    到目前为止,没有任何问题。但突然需求发生了变化,现在我必须在步骤3中添加规则逻辑,即 executeStep3.apply(step3)

    第3步有2个参数,第一个是第2步的输出,第二个是列表规则。
    Step3 应应用所有规则并返回与规则相同的结果。
    对于前。如果有 3 个规则,则步骤 3 应返回 3 个对象的列表。
    假设步骤 3 收到了 PersonDto 的列表有 10 个项目和 3 个项目的规则列表,则第 3 步应返回 10*3 = 30 条记录。
    此外,每个人的规则都会根据命令而有所不同。

  • 问题 2:
    在步骤 3 中,我需要请求对象,以便我可以使用值。 像这样的事情:
    .map(step3 -> executeStep3.apply(step3, rules, request))

哪些设计模式可以提供帮助,以及如何提供帮助?

最佳答案

正如dung ta van已经提到的,首先想到的是责任链模式。我将重用该示例并更改其中的一些内容。

public class ChainOfResponsibility {

    protected List<RequestProcessor> handlers = new ArrayList<>();

    public void addHandler(RequestProcessor handler) {
        this.handlers.add(handler);
    }

    @SuppressWarnings("unchecked")
    public void handle(Request request) {
        handlers
                .stream()
                .reduce(RequestProcessor::andThen)
                .orElseThrow(() -> new RuntimeException("Functions can't be composed"))
                .apply(request, null);
    }

    public interface RequestProcessor<T, R> extends BiFunction<Request, T, R> {

        default <V> RequestProcessor<T, V> andThen(BiFunction<Request, ? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (Request r, T t) -> after.apply(r, apply(r, t));
        }

    }

    public static class PersonExtractor implements RequestProcessor<Void, PersonDto> {
        @Override
        public PersonDto apply(Request request, Void aVoid) {
            return new PersonDto("Nick");
        }
    }

    public static class ValidatePersonHandler implements RequestProcessor<PersonDto, PersonDto> {
        @Override
        public PersonDto apply(Request request, PersonDto personDto) {
            if (personDto.getName() == null) {
                throw new IllegalArgumentException("name can't be null");
            }
            return personDto;
        }
    }

    public static class SetPersonIdHandler implements RequestProcessor<PersonDto, List<?>> {

        private final List<Rule> rules;

        public SetPersonIdHandler(List<Rule> rules) {
            this.rules = rules;
        }

        @Override
        public List<?> apply(Request request, PersonDto personDto) {
            personDto.setId(1);
            rules.forEach(rule -> System.out.println("invoke rule " + rule.toString()));
            return Arrays.asList(personDto, personDto, personDto);
        }

    }

    public static class InsertPersonToDBHandler implements RequestProcessor<List<PersonDto>, Object> {

        @Override
        public List<?> apply(Request request, List<PersonDto> persons) {
            persons.forEach(person -> System.out.println("insert person: " + person.getName() + " to db"));
            return null;
        }
    }

    public static void main(String[] args) {
        ChainOfResponsibility chain = new ChainOfResponsibility();

        chain.addHandler(new PersonExtractor());
        chain.addHandler(new ValidatePersonHandler());
        chain.addHandler(new SetPersonIdHandler(Arrays.asList(new Rule("1"), new Rule("2"))));
        chain.addHandler(new InsertPersonToDBHandler());

        chain.handle(new Request());
    }
}

简而言之,我们引入了RequestProcessor接口(interface),它确实是一个BiFunction。我们将第一个参数绑定(bind)到 Request 上,第二个参数是上一个函数调用的结果。此外,每个处理程序也可以配置规则。

关于java - 使用 java 8 的设计模式建议/实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59451266/

相关文章:

通过命令行执行时出现 Java ClassNotFound 错误

java - 无法解析导入 org.dom4j.*

java - 如何避免 "local variable may not have been initialized"Java 编译错误? (是的,认真的!)

arrays - 以下方法的运行时间如何为 O(N) 且空间复杂度为 O(1)?

c++ - 为什么 std::all_of() 的编码版本与调用 std::all_of() 的基准测试不同?

在 map 上排序点的算法?

spring-boot - Spring Boot 应用程序找不到 SQLite jdbc 驱动程序类

eclipse - 如何在Eclipse中调试Kotlin Spring Boot App?

spring - 在VS代码中将spring应用程序部署到azure时,访问应用程序的端点是什么?

string - JDK 1.4 与 JDK 1.5 中的 java URI 变化