web-dev-qa-db-ja.com

循環的複雑さを減らす方法は?

RequestDTOをWebサービスに送信するクラスに取り組んでいます。リクエストを送信する前に検証する必要があります。

リクエストは3つの異なる場所から送信でき、「requesttype」ごとに異なる検証ルールがあります。 request1には名前と電話番号、request2には住所などが必要です)

フィールド(名前、住所、都市、電話番号など)の長いリストを含むDTOがあり、それがどのタイプの要求であっても送信されたDTOと同じです。

3つの異なる検証メソッドを作成しましたが、タイプに基づいて適切なメソッドが呼び出されます。

これらの各メソッドには、各リクエストタイプに必要なフィールドをチェックするif-elseの長いリストがあります。

_private void validateRequest1(Request request) {
    StringBuilder sb = new StringBuilder();
    if (null == request) {
        throw new IllegalArgumentException("Request is null");
    }
    if (isFieldEmpty(request.getName())) {  *see below
        sb.append("name,"));
    }
    if (isFieldEmpty(request.getStreet())) {
        sb.append("street,"));
    }
    ...
_

isFieldEmpty()は、nullおよびisEmpty()の文字列をチェックし、ブール値を返します

これにより、これらの方法の1つで循環的複雑度が28になります。そのため、この複雑度を減らすことは可能ですか? -もしそうなら、どのように私はそうしますか?

最終的に、私は多くのフィールドをチェックする必要があり、多くのチェックなしでこれがどのように行われるか見ることができません:/

22
Herter

簡単な方法は、チェックを別の方法にプロモートすることです。

private String getAppendString(String value, String appendString) {
    if (value == null || value.isEmpty()) {
        return "";
    }
    return appendString;
}

そして、ifブロックの代わりにこのメソッドを使用できます:

sb.append(getAppendString(request.getStreet(), "street,");

これにより、複雑度が28から3に減少します。常に覚えておいてください:複雑度が高いということは、メソッドがやりすぎていることを示しています。ここで行ったように、問題をより小さな部分に分割することにより、複雑さに対処できます。

35
EmirCalabuch

別のアプローチは、Requestオブジェクト自体でそのコントラクトを実施することです。フィールドが必須であるか、nullにできない場合は、リクエストの作成時にそのようにします。

コンストラクターが存在するときに100%有効で、すぐに使用できるようにリクエストを作成します。

Request toString()メソッドでそのStringバージョンも作成します。自身のレンダリング方法を知っている必要があります。

4
duffymo