我已经阅读过以前的堆栈交换,用Java替换条件逻辑,例如带有状态/策略模式的IF / ELSE,但我不确定我的情况是否适合替换。 我看了一下 - Long list of if statements in Java和Converting many 'if else' statements to a cleaner approach
我基本上是在编写一个文件下载管理器,这些是我的IF / ELSE结构:
基本上我理解你将这四个条件作为哈希映射中的键,然后值是需要发出的“命令”。 但是我相信你仍然需要一个If / Else来决定在作为输入给出的键上调用什么动作。所以我没有看到好处。有人可以解释一下吗?
答案 0 :(得分:4)
我认为你应该使用GoF模式Chain of responsibility。您应该引入两个接口:1)Condition
您将在其中检查正确的条件,例如"如果zip文件不存在"并返回布尔结果 - " true"如果条件满足,否则"否则",2)Execution strategy
,将运行分配有条件的动作,例如"从指定的URL下载它,然后解压缩并读入文件并将zip文件移动到指定的目录。"因此,第一个界面将回答问题"当"和第二个 - "然后"。 "条件"实施和执行战略"实施应该合并到"元组" (或配对,进入等)。这个"元组"应该按顺序移动到收集,你已经描述过了。然后,当你需要处理zip文件时,你将迭代收集,调用条件和检查结果,如果结果是" true"然后调用适当的"执行策略"。此外,条件可以与执行策略结合,并通过两种方法转移到单个接口/实现中。上下文,将描述zip文件的当前状态,可以在条件/执行策略之间传递。
希望这会有所帮助。
<强>更新强> 代码示例(在Java中)。
/**
* All implementations should check proper condition
*/
interface Condition {
/**
* Check if condition is satisfied
*
* @param pathToFile path to target file
* @return 'true' if condition is satisfied, otherwise 'false'
*/
boolean isSatisfied(String pathToFile); //i've made an assumption that you'll manipulate file path for checking file
}
...
/**
* Childs will wrap some portion of code (if you'll use language, that supports lambdas/functors, this interface/implementation can be replaced with lambda/functor)
*/
interface Action {
/**
* Execute some portion of code
*
* @param pathToFile path to target file
*/
void execute(String pathToFile);
}
...
class ZipFileExistsCondition implements Condition {
@Override
public boolean isSatisfied(String pathToFile) {
... //check if zip file exists
}
}
...
class ZipFileDoesNotExists implements Condition {
@Override
public boolean isSatisfied(String pathToFile) {
... //download zip file and move it to some temp directory
//if file downloaded ok, than return 'true' otherwise 'false'
}
}
...
class AlwaysSatisfiedCondition implements Condition {
@Override
public boolean isSatisfied(String pathToFile) {
... //always returns 'true', to run action assigned with this condition
}
}
...
Collection<Map.Entry<Condition, Action>> steps = Arrays.asList(
new AbstractMap.ImmutableEntry<Condition, Action>(new ZipFileExistsCondition(),
new Action() { /*move zip file to zip file directory and read in file*/ }),
new ZipFileDoesNotExists(), new Action() { /*download it from specified URL and then unzip it and read in file and move zip file to specified directory*/ },
new AlwaysSatisfiedCondition(), new Action() { /*create blank file and write it out to disk*/ }
);
...
String pathToFile = ...
...
for(Map.Entry<Condition, Action> step: steps) {
if(!step.getKey().isSatisfied(pathToFile))
continue;
step.getValue().execute(pathToFile);
}
说明: 1)你可以实施条件&#39;作为匿名课程, 2)&#39; AlwaysSatisfiedCondition&#39;可以是单身, 3)如果你正在使用Java / Groovy / Scala,你可以使用Guava / Apache Commons&#39; Predicate&#39;而不是条件&#39;,&#39;功能&#39;或者&#39;关闭&#39;而不是&#39;行动&#39;。
如果您需要在第一次满意后退出&#39;条件和适当的行动执行,然后只是把'休息&#39; /&#39;返回&#39;行动执行后。
答案 1 :(得分:2)
以下是编译此代码的正确方法。这里的关键点是AbstractMap.SimpleImmutableEntry是一个单独的条目。如果要添加更多条目,则需要为每个条目实例化类。
Collection<Map.Entry<Condition,Action>> steps = Arrays.asList
(
(new AbstractMap.SimpleImmutableEntry<Condition,Action>
(new FileExistsCondition(),
new Action()
{
public void execute(String pathToFile){System.out.println("the path to file is srtm " + pathToFile);}
}
)
),
(new AbstractMap.SimpleImmutableEntry<Condition,Action>
(new ZipFileExistsCondition(),
new Action()
{
public void execute(String pathToFile){System.out.println("the path to file is " + pathToFile);}
}
)
),
(new AbstractMap.SimpleImmutableEntry<Condition,Action>
(new ZipFileDoesNotExistCondition(),
new Action()
{
public void execute(String pathToFile){System.out.println("the path to file is " + pathToFile);}
}
)
)
);