19

作業中のコードをリントするたびに、This function's cyclomatic complexity is too high. (7). しかし、どうすればうまくいくように書き直すことができるのか、少し混乱しています。

これは、そのメッセージをスローし続ける関数になります。

function () {
  var duration = +new Date() - start.time,
    isPastHalf = Number(duration) < 250 && Math.abs(delta.x) > 20 || Math.abs(delta.x) > viewport / 2,
    direction = delta.x < 0;

  if (!isScrolling) {
    if (isPastHalf) {
      if (direction) {
        this.close();
      } else {
        if (this.content.getBoundingClientRect().left > viewport / 2 && pulled === true) {
          this.close();
          return;
        }
        this.open();
      }
    } else {
      if (this.content.getBoundingClientRect().left > viewport / 2) {
        if (this.isEmpty(delta) || delta.x > 0) {
          this.close();
          return;
        }
        this.open();
        return;
      }
      this.close();
    }
  }
}

このような状況を避けるために、コードをそのように構成する方法についてアドバイスを聞きたいです。

4

5 に答える 5

5

まず、関数が持つことができる結果は 3 つあります。何もしない、 callthis.close()または callthis.open()です。したがって、理想的には、結果の関数には、使用される結果を決定する if ステートメントが 1 つだけ含まれます。

次のステップは、すべてのブール コードを変数に抽出することです。例var leftPastCenter = this.content.getBoundingClientRect().left > viewport / 2

最後に、ブール論理を使用して段階的に単純化します。

これが私がやった方法です:

まず、すべてのブール変数を抽出します。

function () {
    var duration = +new Date() - start.time,
      isPastHalf = Number(duration) < 250 && Math.abs(delta.x) > 20 || Math.abs(delta.x) > viewport / 2,
      direction = delta.x < 0,
      leftPastCenter = this.content.getBoundingClientRect().left > viewport / 2,
      positiveDelta = this.isEmpty(delta) || delta.x > 0,
      isPulled = pulled === true; // I'll assume the test is needed rather than just using pulled.

    if (!isScrolling) {
        if (isPastHalf) {
            if (direction) {
                this.close();
            } else {
                if (leftPastCenter && isPulled) {
                    this.close();
                    return;
                }
                this.open();
            }
        } else {
            if (leftPastCenter) {
                if (positiveDelta) {
                    this.close();
                    return;
                }
                this.open();
                return;
            }
            this.close();
        }
    }
}

引き出すのが最も簡単な部分は、isScrollingが true の場合、何も起こらないことに気付くことです。これにより、1 レベルのネストがすぐに取り除かれます。

    // above same
    if (isScrolling) { return; }

    if (isPastHalf) {
        if (direction) {
            this.close();
        } else {
            if (leftPastCenter && isPulled) {
                this.close();
                return;
            }
            this.open();
        }
    } else {
        if (leftPastCenter) {
            if (positiveDelta) {
                this.close();
                return;
            }
            this.open();
            return;
        }
        this.close();
    }
}

this.open()次に、呼び出されたケースを見てください。isPastHalfが true の場合、との場合にthis.open()のみ呼び出されます。が false の場合、次の場合にのみ呼び出されます。!direction!(leftPastCenter && isPulled)isPastHalfthis.open()leftPastCenter!positiveDelta

    // above same
    if (isScrolling) { return; }

    if (isPastHalf) {
        if (!direction && !(leftPastCenter && isPulled)) {
            this.open();
        } else {
            this.close();
        }
    } else {
        if (leftPastCenter && !positiveDelta) {
            this.open();
        } else {
            this.close();
        }
    }

ifs を反転すると (this.close()最初に来る)、コードが少しきれいになり、最終バージョンが得られます。

    function () {

    var duration = +new Date() - start.time,
      isPastHalf = Number(duration) < 250 && Math.abs(delta.x) > 20 || Math.abs(delta.x) > viewport / 2,
      direction = delta.x < 0,
      leftPastCenter = this.content.getBoundingClientRect().left > viewport / 2,
      positiveDelta = this.isEmpty(delta) || delta.x > 0,
      isPulled = pulled === true; // I'll assume the test is needed rather than just using pulled.

    if (isScrolling) { return; }

    if (isPastHalf) {
        if (direction || (leftPastCenter && isPulled)) {
            this.close();
        } else {
            this.open();
        }
    } else {
        if (!leftPastCenter || positiveDelta) {
            this.close();
        } else {
            this.open();
        }
    }
}

コードベースを知らずにこれ以上のことを行うのは困難です。注意すべきことの 1 つはdirection、私の新しい変数がほぼ同じであることです。削除して使用positiveDeltaすることもできます。また、ブール値の名前としては適切ではありません。positiveDeltadirectiondirectionmovingLeft

于 2013-07-29T15:58:29.420 に答える