Java 处理基于条件的方法调用的最佳设计
处理基于条件的方法调用的最佳设计模式是什么?条件基于字符串比较。我知道basic if-else或switch可以解决这个问题,但仍在寻找其他解决方案 示例: 用户按顺序输入字符串Java 处理基于条件的方法调用的最佳设计,java,design-patterns,Java,Design Patterns,处理基于条件的方法调用的最佳设计模式是什么?条件基于字符串比较。我知道basic if-else或switch可以解决这个问题,但仍在寻找其他解决方案 示例: 用户按顺序输入字符串foo1、foo2和foo3。现在程序根据这些输入调用一个方法,即: if (input.equals("foo1")) fun1(); else if(input.equals("foo2")) fun2(); 等等 另外,fun1()和fun2()的功能是完全独立的。这取决于它们。在你的情况下,没有一
foo1
、foo2
和foo3
。现在程序根据这些输入调用一个方法,即:
if (input.equals("foo1"))
fun1();
else if(input.equals("foo2"))
fun2();
等等
另外,
fun1()
和fun2()
的功能是完全独立的。这取决于它们。在你的情况下,没有一个。但通常您会通过某种形式的多态性或模板方法模式来解决这个问题。但您的数据模型似乎并没有以这种方式设计,所以您几乎完蛋了,您将不得不创建一个丑陋的嵌套IF结构。或者,您可以稍微重构它,并使用模板方法模式。在这种情况下,您可以使用工厂方法模式根据字符串创建不同的模板,这些模板中的每一个都有一个不同的TemplateMethod()
,将被调用。这允许您平等地对待所有对象,但有一个部分(模板方法)可以独立操作
有关更深入的说明,请参见:
编辑:添加了不那么糟糕的工厂方法的示例
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(""));
}
}
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";
}
}
在您的情况下,我将考虑代码< > EnUM <代码>和
- 如果您使用拼写错误的字符串来调用函数(
,而不是getFunction(“foO”)
),您不知道如何调试它,编译器不会告诉您任何事情getFunction(“foO”)
- 如果您错误地使用了两个相同的字符串来引用两个不同的方法,那么您也无法检测到它
- 您不能遍历所有字符串,
有一个enum
方法用于该操作values()
enum
public enum Function{
foo1,
foo2;
}
您可以使用Runnables而不是factory来简化它:
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(){}
}
公共类路由器{
私人地图;
公共路由器(){
this.map=新的HashMap();
map.put(“foo1”,新的Runnable(){
运行(){
fun1();
}
});
map.put(“foo2”,新的Runnable(){
运行(){
fun2();
}
});
}
public void doRoot(String命令)引发IllegalArgumentException{
Runnable r=map.get(命令);
if(r==null){
抛出新的IllegalArgumentException(“无效命令:”+命令);
}
r、 run();
}
fun1(){}
fun2(){}
}
您能提供更多详细信息吗<代码>条件基于字符串比较?请举例说明这个问题太宽泛了。根据需要,你可以考虑使用有限状态机或其他技术。仅方法名就足够了吗?用字符串引用方法对我来说是双倍的工作量。即使工厂模式也使用丑陋的if-else-if结构(只是一个简单的示例shape工厂类)。现在想象成百上千种不同的形状(圆形、正方形、五角大楼……等等),这个shapefactory类看起来会很糟糕。我只是在寻找更好的方法,不一定。这是个糟糕的例子。一个更好的例子是在工厂中保留一个“Map”,然后查找所需的类,或者从IoC容器中将其作为依赖项获取,或者只是创建一个新实例。@avenger我已更新了我的答案,以包含一个详细说明我答案的示例。理想情况下,您应该使用IoC容器(如Spring BeanFactory或Guice Injector)来创建和处理对象生命周期,而不是使用反射。但设置它有点超出了问题的范围。另外@PhamTrung也正确,您应该在字符串值上使用类型安全枚举器。
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(){}
}