在多个if语句中调用正则表达式检查方法时使用哪种模式或方法?

时间:2018-06-13 11:28:59

标签: java regex design-patterns factory-pattern

我在班上创建了一个工厂模式。

在这个类中,我根据传入的String参数注入了实现Command接口的类。

工厂类

@Component
@RequiredArgsConstructor
public class CommandFactory {
    private final ACommand aCommand;
    private final BCommand bCommand;
    private final CCommand cCommand;
    private final DCommand dCommand;
    private final ECommand eCommand;
    private final FCommand fCommand;

    public Command createCommand(String content) {
        if (aCommand.isMatching(content)) {
            return aCommand;
        } else if (bCommand.isMatching(content)) {
            return bCommand;
        } else if (cCommand.isMatching(content)) {
            return cCommand;
        } else if (dCommand.isMatching(content)) {
            return dCommand;
        } else if (eCommand.isMatching(content)) {
            return eCommand;
        } else if (fCommand.isMatching(content)) {
            return fCommand;
        } else {
            return null;
        }
    }

isMatching()方法中有不同的正则表达式,我试图弄清楚如何处理这个传入的字符串。

我正在寻找一种更清晰的方法来摆脱这些顺序if语句。因为每当我在这个工厂里创建一个新类时,我都会添加另一个if语句。

3 个答案:

答案 0 :(得分:1)

也许Stream可以提供帮助吗?

Stream<Command> stream = Stream.of(aCommand, bCommand, cCommand ...);
return stream.filter(x -> x.isMatching(content)).findFirst().orElse(null);

现在每次添加新类时,只需在第一行添加一个新对象。

答案 1 :(得分:1)

如果你想摆脱顺序if语句你可以使用流(如建议的用户Sweeper)或循环,我也建议返回和可选,这使得null处理更清晰客户端。

以下是两个建议的选项,用于摆脱if else重复一个循环,另一个循环使用流:

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class CommandPatternExample {

    private List<Command> candidates = Arrays.asList(new ACommand(), new BCommand(), new CCommand());

    public Optional<Command> createCommand(String content) {
        for(Command command : candidates) {
            if(command.isMatching(content)) {
                return Optional.of(command);
            }
        }
        return Optional.empty();
    }

    public Optional<Command> createCommandStream(String content) {
        return candidates.stream().filter(c -> c.isMatching(content)).findFirst();
    }
}

interface Command<T> {
    void execute(T obj);
    boolean isMatching(String s);
}

class ACommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "A".equals(s);
    }
}

class BCommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "B".equals(s);
    }
}

class CCommand implements Command<String> {

    @Override
    public void execute(String obj) {

    }

    @Override
    public boolean isMatching(String s) {
        return "C".equals(s);
    }
}

答案 2 :(得分:0)

地图可能是个好主意。这意味着如果将命令实例放入映射中作为值,其中键可以与传入的String匹配。然后,不是使用效率O(n)进行顺序搜索,而是可以获得更好的性能O(1)。这是一个简短的答案。

除此之外还有一个开源的java库MgntUtils(由我提供),其中包含一些名为&#34;自我实例化工厂&#34;基本上它为您管理和工厂。您需要做的就是创建一个实现某个接口的类,该实用程序会将它添加到基于地图的工厂中。它可能对你有用。这是一篇文章的link,它解释了库中的实用程序以及库的位置(Github和Maven中心)。在文章中查找段落&#34; 生命周期管理(自我实例化工厂)&#34;。此外,库还附带了详细的javadoc和该功能的代码示例。