我在Java
中编写了一个脚本(不确定是否是写术语)。
用户可以通过两种方式指定环境变量:命令行或在文件中。
命令行如下所示(用~~~
分隔)
ENV1=1~~~ENV2=String2
文件如下:
setenv ENV1 1
setenv ENV2 String2
我编写了一个函数,该函数返回env的集合(因此输出为:{ENV2=String2, ENV1=1}
)。
它看起来如下:
public Map<String, String> getEnvs() {
final String envArg = getOption(cmdNames.ENV); // returns the path or the command-line options
if (null != envArg && !"".equals(envArg) && envArg.contains("=")) {
final String varArray[] = envArg.split("~~~"); // split by a special string
final Map<String, String> new_vars = new HashMap<String, String>();
for (final String var : varArray) {
final String varName = var.split("=")[0];
String varValue = var.split("=")[1];
if (!varValue.contains("\"") && varValue.contains(" ")) {
varValue = "\"" + varValue + "\"";
}
new_vars.put(varName, varValue);
}
return new_vars;
}
return null;
}
现在,我为命令行选项编写了一个函数。我想添加对文件选项的支持。问题在于这些选项的外观不同-我需要用~~~
分割其中一个,而用setenv
分割另一个。
我很高兴听到关于如何在同一getEnvs
函数中添加对文件选项的支持的建议。
我脑子里已经有了一些实现,但是它变得一团糟,我正在寻找最干净的方法。 (据我了解,我们需要将文件中的数据插入到数组中并用setenv
进行拆分,但是我们还需要在name
和value
之间进行拆分-感觉代码可以使用了两次,但我不确定哪个部分可以解决问题。
答案 0 :(得分:0)
您似乎试图解决的问题似乎可以通过策略模式来最好地解决。
文件的内容和命令行都可以用字符串表示。这些字符串可以由某种类型的解析器处理,这些解析器可以根据您的意愿使用不同的策略。
看起来像这样
public static void main(String... args) throws IOException{
boolean parseFromFile = true; //whatever criteria you want to use
String content;
Parser p;
String fileName = "yikes";
if(parseFromFile){
p = new Parser(new FileParseStrategy());
//we need to read contents of file prior to parsing
content = Files.readAllLines(Paths.get(fileName)).stream()
.collect(Collectors.joining(System.lineSeparator()));
}
else {
p = new Parser(new CmdLineParseStrategy());
content = getContent(cmdNames.ENV); //just coping what you used.
}
Map<String, String> vars = p.run(content);
}
public class Parser{
final ParseStrategy parseStrategy;
public Parser(ParseStrategy ps) {
this.parseStrategy = ps;
}
public Map<String, String> run(String input){
return parseStrategy.parse(input);
}
}
public interface ParseStrategy {
Map<String, String> parse(String input);
}
public class FileParseStrategy implements ParseStrategy{
@Override
public Map<String, String> parse(String input) {
Map<String, String> result = new HashMap<>();
for(String line : input.split("\r?\n|\r")) {
String[] parts = validate(line.split(" "));
result.put(parts[1], parts[2]);
}
return result;
}
private String[] validate(String[] parts) {
if(parts.length != 3) {
throw new IllegalArgumentException("3 parts needed");
}
if(!parts[0].equalsIgnoreCase("setenv")){
throw new IllegalArgumentException("unrecognized cmd");
}
return parts;
}
}
//given implementation of parsing from command line.
public class CmdLineParseStrategy implements ParseStrategy {
@Override
public Map<String, String> parse(String envArg) {
if (null != envArg && !"".equals(envArg) && envArg.contains("=")) {
final String varArray[] = envArg.split("~~~"); // split by a special string
final Map<String, String> new_vars = new HashMap<String, String>();
for (final String var : varArray) {
final String varName = var.split("=")[0];
String varValue = var.split("=")[1];
if (!varValue.contains("\"") && varValue.contains(" ")) {
varValue = "\"" + varValue + "\"";
}
new_vars.put(varName, varValue);
}
return new_vars;
}
return null;
}
}