如何创建动态IF语句?反射?

发布于 2024-12-04 19:45:24 字数 475 浏览 0 评论 0原文

是否可以通过反射创建动态 IF 语句?

我看过 BeanShell 的示例(如下所示: 动态 if 语句评估问题字符串比较),但我想知道是否可以在没有 BeanShell 的情况下完成此操作,并指出一些示例以适应我的需求。

基本上我有一个以下形式的语句:A运算符B。A

和B可以是数字(双精度数或整数)或字符串,但A始终与B的类型相同。 运算符可以是 !=、==、>=、>、<=、<,甚至其他可以通过自己的类定义行为的运算符,这是我使用反射的另一个原因,因为我可以采取该字符串并使用反射来调用适当的方法。

我希望(必须)避免分支“if”和“switch”,因为变化太多,并且会随着用户生成的输入而不断变化。

Is it possible with reflection to create a dynamic IF statement?

I have seen examples with BeanShell (like this: Dynamic if statement evaluation problem with string comparison) but i would like to know if it was possible to do it without BeanShell, and be pointed to some examples to adapt to my needs.

Basically i have a statement of the form: A operator B.

A and B can be numbers (Doubles or ints) or strings, but always A is the same type as B.
operator can be !=, ==, >=, >, <= ,<, and even others which behavior may be defined trough a class of their own, another reason why i will use reflection, since i can take that string and use reflection to invoke the appropriate method.

I want (must) to avoid branching "if" and "switch" because the variations are too many and will change constantly with user generated input.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

晨与橙与城 2024-12-11 19:45:25

您可以创建一个工厂,为给定的输入返回正确的运算符。

public class OperatorFactory {
  private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>();

  static {
    OPERATORS.put("<Number", new LessThanNumOperator());
    OPERATORS.put("==Number", new EqualToNumOperator());
    OPERATORS.put("<String", new LessThanStringOperator());
    ...
  }

  public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) {
    String key = someUserSpecifiedOp;
    if (Number.class.isAssignableFrom(paramType)) {
      key += "Number";
    } else if (String.class.isAssignableFrom(paramType)) {
      key += "String";
    }
    return OPERATORS.get(key);
  }
}

public interface Operator<T> {
  public boolean execute(T lhs, T rhs);
}

public class LessThanNumOperator implements Operator<Number> {
  public boolean execute(Number lhs, Number rhs) {
     return  lhs.doubleValue() < rhs.doubleValue();
  }
}

然后使用它:

OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs);

You can create a factory that returns the correct operator for the given input.

public class OperatorFactory {
  private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>();

  static {
    OPERATORS.put("<Number", new LessThanNumOperator());
    OPERATORS.put("==Number", new EqualToNumOperator());
    OPERATORS.put("<String", new LessThanStringOperator());
    ...
  }

  public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) {
    String key = someUserSpecifiedOp;
    if (Number.class.isAssignableFrom(paramType)) {
      key += "Number";
    } else if (String.class.isAssignableFrom(paramType)) {
      key += "String";
    }
    return OPERATORS.get(key);
  }
}

public interface Operator<T> {
  public boolean execute(T lhs, T rhs);
}

public class LessThanNumOperator implements Operator<Number> {
  public boolean execute(Number lhs, Number rhs) {
     return  lhs.doubleValue() < rhs.doubleValue();
  }
}

And then use it:

OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs);
十六岁半 2024-12-11 19:45:25

反思是没有帮助的。反射为您提供有关代码结构(类、方法、属性)的信息,但它不允许您更改和更新现有代码。

不要尝试生成新代码,而是尝试添加一种方式让用户根据他们的输入更改应用程序的行为。

我不知道你到底想做什么。发布一些用户输入和预期行为的示例,以帮助缩小选项范围。但这里有一些事情可能会帮助您完成任务:

  • 拥有一个用户界面,可以帮助您的用户选择操作数的时间,其中包含值的文本字段和运算符的下拉框。简单的解决方案,但我不会推荐它,因为它可能会增加用户界面的复杂性。
  • 为您的表达式编写一个解析器。为这种非常简单的语言(A 运算符 B)编写一个简单的解析器应该可以在合理的时间内完成。
  • 领域特定语言。允许应用程序的用户编写一些脚本,这些脚本由应用程序解释并以某种方式响应。您可以想象 DSL 包含简单的比较,结果将影响您的应用程序的行为。看看 Groovy,它对于这个用例来说是一种很好的语言。

Reflection won't help. Reflection gives you information about your code structure (classes, methods, attributes), but it doesn't allow you to change and update existing code.

Don't try to generate new code, try instead of adding a way for users to change the behaviour of your app depending on their input.

I don't know exactly what you are trying to do. Post some examples of user input and expected behaviour to help narrow the options down. But here is a few things that might help you in your task:

  • Have a user interface that helps your user select the time of the operands, with text fields for values, and a dropdown box for the operator. Simple solution, but I wouldn't recommend it as it may add complexity to the user interface.
  • Write a parser for your expressions. Writting a simple parser for this very simple language (A operator B) should be doable in reasonable time.
  • Domain Specific Languages. Allows the users of your application to write some scripts that get interpreted by your application and respond in some way. You could imagine a DSL consisting in simple comparisons, and the results will influence the behaviour of your app. Have a look at Groovy, it is a good language for this use case.
红尘作伴 2024-12-11 19:45:25

您可以创建一个像这样的接口

public interface MyComparator
{
    public boolean matches(String operator);
    public boolean compare(String a, String b);
}

然后您可以创建多少个您想要的类都实现这样的接口

public class MyEquals implements MyComparator
{
    @Override
    public boolean matches(String operator)
    {
    return "==".equals(operator);
    }

    @Override
    public boolean compare(String a, String b)
    {
    return a.equals(b);
    }
}

并像这样加载它们:

Class compClass = Class.forName(classname);
MyComparator comp = (MyComparator)compClass.newInstance();

您可以准备所有可用运算符的列表并迭代它,甚至配置运算符列表在属性文件上。

You could make a interface like this

public interface MyComparator
{
    public boolean matches(String operator);
    public boolean compare(String a, String b);
}

Then you could make how many classes you want all implementing the interface like this

public class MyEquals implements MyComparator
{
    @Override
    public boolean matches(String operator)
    {
    return "==".equals(operator);
    }

    @Override
    public boolean compare(String a, String b)
    {
    return a.equals(b);
    }
}

and load them like this:

Class compClass = Class.forName(classname);
MyComparator comp = (MyComparator)compClass.newInstance();

you could so prepare a list of all available operators and iterate over it and even have the list of operators configured on a properties file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文