我在班上创建了一个工厂模式。
在这个类中,我根据传入的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语句。
答案 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和该功能的代码示例。