处理基于条件的方法调用有哪些最佳设计模式?条件基于字符串比较。我知道基本的if-else-if或switch可以解决它但仍在寻找其他解决方案。
示例:
用户按顺序输入字符串foo1
,foo2
和foo3
。现在程序根据这些输入调用一种方法,即:
if (input.equals("foo1"))
fun1();
else if(input.equals("foo2"))
fun2();
等等。
此外,fun1()
和fun2()
的功能完全相互独立。
答案 0 :(得分:0)
这取决于。在你的情况下,没有一个。但通常你会通过某种形式的多态或模板方法模式来解决这个问题。但是你的数据模型似乎并没有以这种方式设计,所以你几乎搞砸了,而且你必须制作一个丑陋的嵌套IF结构。或者,您可以稍微重构它并使用模板方法模式。在这种情况下,您可以使用Factory方法模式基于String创建不同的模板,这些模板中的每一个都将具有将被调用的不同TemplateMethod()
。这允许您平等对待所有对象,但有一个部分(模板方法)独立行动。
有关更深入的说明,请参阅:http://en.wikipedia.org/wiki/Template_method_pattern
编辑:添加了一些不太蹩脚的Factory方法的示例。
TemplateFactory.java
public class TemplateFactory {
private Map<String, Class> map;
public TemplateFactory() {
this.map = new TreeMap<>();
map.put("Template 1", Template1.class);
map.put("Template 2", Template2.class);
}
public BaseTemplate createBaseTemplate(String comparison)
{
if (!map.containsKey(comparison))
{
return null;
}
try {
return (BaseTemplate) map.get(comparison).getConstructor().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
TemplateFactory tf = new TemplateFactory();
BaseTemplate t1 = tf.createBaseTemplate("Template 1");
BaseTemplate t2 = tf.createBaseTemplate("Template 2");
System.out.println(t1.templateMethod(""));
System.out.println(t2.templateMethod(""));
}
}
BaseTemplate.java
public abstract class BaseTemplate {
public String doSomething()
{
// whatever
return "Hello";
}
public int anotherRealMethod(String data)
{
//also whatever
return 0;
}
public abstract String templateMethod(String data);
}
Template1.java
public class Template1 extends BaseTemplate {
@Override
public String templateMethod(String data) {
return "Template 1";
}
}
模板2.java
public class Template1 extends BaseTemplate {
@Override
public String templateMethod(String data) {
return "Template 2";
}
}
答案 1 :(得分:0)
在您的情况下,我会考虑enum
和switch case
的组合。我们不应该使用字符串的原因是:
如果你使用拼写错误的字符串来调用你的函数(getFunction("foO")
而不是getFuntion("foo")
),你就不知道如何调试它,编译器不会告诉你你什么。
如果您错误地使用了两个相同的String来引用两种不同的方法,那么您也无法检测到它。
您无法遍历所有字符串,enum
有values()
方法。
所以我的建议是使用enum
public enum Function{
foo1,
foo2;
}
答案 2 :(得分:0)
您可以使用Runnables而不是工厂来简化它:
public class Router {
private Map<String, Class> map;
public Router() {
this.map = new HashMap<>();
map.put("foo1", new Runnable(){
run(){
fun1();
}
});
map.put("foo2", new Runnable(){
run(){
fun2();
}
});
}
public void doRoot(String command) throws IllegalArgumentException {
Runnable r = map.get(command);
if(r == null){
throw new IllegalArgumentException("invalid command: " + command);
}
r.run();
}
fun1(){}
fun2(){}
}