简体   繁体   English

如何避免重复的if陈述?

[英]How can I avoid repeated if-statement?

I write a java application to handle log file had millions of line In program there is such a pseudo code 我写了一个Java应用程序来处理日志文件有上百万行,在程序中有这样的伪代码

if(optionA is On)
  call object A's method

if(optionB is On)
  call object B's method

if(optionC is On)
  call object C's method
...

The options in IFs are config value get from a config file This pseudo code called in each log line, so it called millions of time IF中的选项是从配置文件获取的配置值。此伪代码在每个日志行中调用,因此它调用了数百万次

Because of speed and simplicity, I want to remove this multi IFs. 由于速度和简便性,我想删除此多个IF。 To see such a many IFs are unpleasant to me. 看到这么多的中频对我来说是不愉快的。 Is theare a good way to get around this annoying IFs? theare是解决这种烦人的IF的好方法吗?

If the objects share a common interface, you could create a method like this: 如果对象共享一个公共接口,则可以创建如下方法:

private void callOptional(myInterface obj, boolean flag) {
  if (option) obj.method();
}

That way you have eliminated the IFs. 这样,您就消除了IF。 But you still have a long list of common code. 但是您仍然可以找到很多常用代码。 To make it more DRY, I'd add the object reference to the list where you store the options and then just do a for loop: 为了使其更干燥,我将对象引用添加到存储选项的列表中,然后执行for循环:

for (OptionObjectPair ooPair : optionObjectList) {
  callOptional(ooPair.obj, ooPair.flag)
}

You can then even change the interface of the callOptional method to take an OptionObjectPair directly. 然后,您甚至可以将callOptional方法的接口更改为直接采用OptionObjectPair。

If the method is the same for all objects, then create a option-to-object hash table and call the method based on the option. 如果所有对象的方法都相同,则创建一个“选项到对象”哈希表并基于该选项调用该方法。

HashMap<Option,ActionObject> map ;
for (Option option: map.keySet()) {
    if (optionIsTrue(option)) {  
        map.get(option).performAction() ;
    }
}

Long sequences of if statements are not always a bad thing. 较长的if语句序列并不总是一件坏事。 If you want to do it the right way though, you have to define the mapping of your options to their "handlers" in a data structure instead of hardcode it in if statements. 如果您想以正确的方式进行操作, 必须在数据结构中定义选项到其“处理程序”的映射,而不是在if语句中对其进行硬编码。

You can define a one-method interface and have A , B and C (in your example) implement it: 您可以定义一个方法接口,并让ABC (在您的示例中)实现它:

public interface OptionHandler { // For lack of a better name...
    void handleOption(); // You could pass parameters here
}

You can then define a map of the options to their handlers: 然后,您可以定义选项到其处理程序的映射:

private final Map<Option, OptionHandler> optionHandlers = new HashMap<Option, OptionHandler>();

You would then replace your sequence of if statements with something like: 然后,您可以将if序列替换为以下内容:

for (Option option : options) {
    if (!option.isOn()) {
        // Skip off option
        continue;
    }
    OptionHandler handler = optionHandlers.get(option);
    if (handler != null) {
        handler.handleOption();
    }
}

It really depends what you want to optimize (see templatetypedef's comment). 这实际上取决于您要优化的内容(请参见templatetypedef的注释)。 If you just want to reduce code footprint you may do something like this 如果您只是想减少代码占用空间,则可以执行以下操作

// let's assume you have an Option interface with isTrue() method
// let's assume you have an Action interface with performAction() method

Map<Option,Action> actions = new HashMap<Option,Action>();
// initialize actions with instance of your objects so that you have:
// optionA -> actionA
// optionB -> actionB
// etc.
// this is done only once

Option[] currentOptions;
// read the current option values and put them in an array
for (int i = 0; i < currentOptions.lengt; i++) {
    if (currentOptions[i].isTrue())
        actions.get(currentOptions[i]).performAction();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM