【问题标题】:Improve code to avoid loop and conditions改进代码以避免循环和条件
【发布时间】:2021-03-04 16:16:20
【问题描述】:

我正在解码一个文件并且在我的代码中有两个函数。第一个是提取需要的值,需要分成几部分,而第二个是解码部分并给出输出。

第二个函数有许多 if 语句以正确的方式处理实际正确的部分,因为每个部分需要以不同的方式处理。 由于块的长度,这些语句在输出和处理方面的差异很小。

  1. 我知道don't-repeat-yourself-principle,但由于每个部分的处理方式不同,我不知道如何改进实际代码。
  2. 每个部分使用一个类好还是应该将代码分成两个文件,一个用于提取值,一个用于解码?
  3. 除了使用 while 循环和许多 if 条件之外,还有其他方法可以循环访问各个部分并对其进行处理吗?

【问题讨论】:

    标签: if-statement optimization refactoring dry


    【解决方案1】:

    您只能更改 if 上的一些变量,然后在最后,只调用 1 次 readRaw 和最后的其他常见代码:

    while (True){
    
        extract a 
        
        if (a == 100){
            break
        }
        
        if (a == 1){
            offsetVar = 0
            nbytesVar=2
            sizeVar=2
            # other stuff with these values
        }
        
        if (a == 2){
            offsetVar = 2
            nbytesVar=4
            sizeVar=4
            #other stuff with these values
        }
        
        ...
        
        if (a == 29){
            offsetVar = 8
            nbytesVar=2
            sizeVar=2
            # other stuff with these values
        }
        
        #    ONLY 1 TIME CALL COMMON CODE
        this <- readRaw (file = test_filename, offset=offsetVar, nbytes=nbytesVar, size=sizeVar)
        that <- blockValue(this)
        cat(paste("value a is:", a,
                      "other values:", otherValues))
    }
    

    【讨论】:

    • @3zm4script 你也可以用一个switch case来改变所有的if(代码少很多if)
    • 问题是根据a的值在一个语句中多次调用readRaw和blockValue。所以在一个语句中,例如它被调用一次,在另一个语句中被调用三次
    【解决方案2】:

    目前,您的循环什么都不做:如果您完全删除循环和 ifs,然后按顺序执行所有操作,您的代码已经更短了:

    code for a == 1
    code for a == 2
    …
    

    ……但我们当然可以做得更好。你说你的偏移量和字节数没有模式。所以将它们放入列表中(向量不起作用,因为你需要嵌套它们,因为每个 a 值可以有多个关联值):

    offsets = list(
        c(0L, 2L),
        2L,
        8L
    )
    nbytes = list(
        c(2L, 2L),
        4L,
        2L
    )
    
    read_value = function (a, offset, nbytes) {
        this = readRaw(test_filename, offset = offset, nbytes = nbytes)
        that = blockValue(this)
    }
    
    do_stuff = function (a, offset, nbytes) {
        value = read_value(a, offset, nbytes)
        # do other stuff with value
        message('value is: ', a, ' other values: ', otherValues)
    }
    
    for (a in 1 : 100) {
        mapply(do_stuff, a, offsets[[a]], nbytes[[a]])
    }
    

    【讨论】:

    • 循环是用来遍历文件的,因为每次我提取不同的a。循环后有一个计数器,用于确定应在哪个点进一步读取文件。计数器由语句中的其他变量组成。
    【解决方案3】:

    在没有实际代码的情况下,我能给出的看似最好的解决方案是:

    1. 将代码中重复的部分提取到自己的方法中,然后调用提取的方法;这使代码保持干燥。
    2. 将条件块中的代码提取到它们自己的方法中*。这使高级方法保持抽象(而不是详细说明整个工作)并保持您的方法小。

    * 第 2 点的示例:

    您可以转换一些如下所示的代码:

    public void myMethod() {
        if (someCondition) {
            line1;
            line2;
            line3;
        } else if (someOtherCondition) {
            line4;
            line5;
            line6;
        } else {
            line7;
            line8;
            line9;
        }
    }
    

    到:

    private void someConditionMethod() {
        line1;
        line2;
        line3;
    }
    
    private void someOtherConditionMethod() {
        line4;
        line5;
        line6;
    }
    
    private void finalMethod() {
        line7;
        line8;
        line9;
    }
    
    public void myMethod() {
        if (someCondition) {
            someConditionMethod();
            return;
        }
    
        if (someOtherCondition) {
            someOtherConditionMethod();
            return;
        }
    
        finalMethod();
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-03
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多