减少嵌套

时间:2018-01-28 23:08:43

标签: java android

在某些代码中进行成像,您需要进行大量检查,并且必须按特定顺序进行。例如:

伪代码:

int a, b, c, ...... y, z
a = Random(0,10);
if (a > 5)
    b = Random(a,100);
    if (b > 50)
        c = Random(b,200);
        if (c > 100)
            ......
            ...... if (y > 10000)
                       z = Random(y, 11000);
int d = a + b + c + ...... + y + z;

上述计算必须按顺序进行,并产生大量嵌套,这使得代码最终难以阅读。我知道上面的算法可以通过使用int数组和for循环来处理,但如果计算更复杂并且在每次检查后有所不同呢?解决这个问题的最佳方法是什么?

这就是我的想法:

while (true)
{
    if (a < 6)
        break;

    b = Random(a,100);
    if (b < 51)
        break;

    c = Random(b,200);
    if (c < 101)
        break;

    ......

    if (y < 10001)
        break;

    z = Random(y, 11000);
}   
int d = a + b + c + ...... + y + z;

但是,Android Studio抱怨while语句没有循环...

好的,让我们看一个不同的例子:

int a, b, c, ...... y, z
    a = Random(0,10);
    if (a > 5)
        b = Random(a,100) + 1 * 5; // some complicated operation
        if (b > 50)
            c = Random(b,200) + 4 - log10(,10); // some more complicated operation
            if (c > 100)
                ......
                ...... if (y > 10000)
                           z = Random(y, 11000) * 999^a - b + log2(log10(d)); // well you get the idea

    int d = a * b + c - ...... / y ^ z;

可编辑示例:

activity_main.xml:只需添加ID为TextView

resultTextView窗口小部件
<TextView
    android:id="@+id/resultTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

MainActivity.java:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.util.Random;

import static java.lang.Math.log10;
import static java.lang.Math.max;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        doSomeCal();
        ((TextView) findViewById(R.id.resultTextView)).setText(String.valueOf(doSomeCal()));
    }

private int doSomeCal() {
    int a, b = 0, c = 0, d = 0, e = 0;
    int val = 0;
    Random r = new Random();

    a = r.nextInt(10);
    if (a > 5) {
        b = takeRandom(r, a, 100) + 5;
        if (b > 50) {
            c = takeRandom(r, b, 200) + 4 - (int) log10(111);
            if (c > 100) {
                d = takeRandom(r, c, 500) * 6 + (int) log10(c);
                if (d > 230) {
                    e = takeRandom(r, d, 11000) * 999 ^ a - b + (int) log10(log10(d));
                    val = a * b + c * e - d;
                }
            }
        }
    } else {
        val = -999;
    }

    if (val > 516) {
        if (d > 200)
            return e > 1000 ? val + d + e : val + d;
        else
            return e > 1000 ? val + 20 + e : val;
    }
    if (val > 432) {
        if (b > 30) {
            return c > 60 ? val + b : val + c;
        } else {
            return val + c;
        }
    }
    if (val > 20) {
        if (b > 30) {
            return a > 3 ? val + a : val + b;
        } else {
            return a < 6 ? val - a : val - b;
        }
        if (val < 0) {
            if (a > 3 && b > 30)
                return c < 80 ? val - a * b + c : val + a + b;
        }
    }
    return val + 999;
}

2 个答案:

答案 0 :(得分:1)

不幸的是,如果您需要执行嵌套检查,那么您需要执行嵌套检查。如果检查失败,您可以将逻辑反转为保留,但只会通过多次调用break;return;来保存缩进并延长代码。

你的循环没有保存任何代码,事实上它引入了更多,据我所知没有做什么......也许你会喜欢这种美学:

int[] minimums = new int[] {5, 50, ...};
int[] upperRanges = new int[] {100, 200, ...};
int[] values = new int[minimums.length];
int result = 0;
for (int i = 0; i < minimums.length; i++) {
    values[i] = Random(0, upperRanges[i]); // still pseudo code
    result += values[i];
    if (values[i] <= minimums[i])
        break;
}
// result is the cumulative sum
// If you don't reference values later, then you can replace it with a regular int to be used again and again.

仅供参考,values initialized to all zeros.

答案 1 :(得分:0)

如果你可以将数据包装在一个对象中(数组没问题),我会使用chain of responsibility pattern(或至少接近它的东西)并让对象管理所需的内容。这会产生更详细的声明,但检查本身会更清晰。

我正在使用匿名类,但您可以将其分解为普通类,以使代码更具可读性。

repositories {
   flatDir {
       dirs "../../node_modules/your_project/android/libs"
   }
}