web-dev-qa-db-ja.com

getterメソッドに保存された値を変更させるのは悪い習慣ですか?

クラスのバージョン2のようにgetterメソッドを変更するのは悪い習慣ですか。

バージョン1:

 public String getMyValue(){
     return this.myValue
 }

バージョン2:

 public String getMyValue(){

    if(this.myValue == null || this.myValue.isEmpty()){
       this.myValue = "N/A";
    }

    return this.myValue;
 }
68
Suranga

getterメソッドがオブジェクトの内部状態を変更する場合、実際にはかなり悪い習慣だと思います。

同じことを達成するために、私はちょうどreturning_"N/A"_を提案します。

  • 一般的に言えば、この内部フィールドは、getterメソッドを使用する必要がない他の場所(内部)で使用される可能性があります。したがって、最終的には、foo.getMyValue()を呼び出すと、実際にはfooの動作が変わる可能性があります。

または、nullから_"N/A"_への変換はsetterで実行できます。つまり、nullが渡された場合、内部値を_"N/A"_に設定できます。


一般的な注意:
_"N/A"_などの状態は、コードに依存するAPIまたは他のインスタンスによって予期される場合にのみ追加します。そうでない場合は、プログラミング言語で使用できる標準のnull型に依存する必要があります。

116
fgysin

私の意見では、あなたがlazy-loading(その場合はそうではありません)、ゲッターは値を変更しないでください。だから私はどちらかだろう:

セッターに変更を入れます

public void setMyValue(String value) {
    if(value == null || value.isEmpty()){
        this.myValue = "N/A";
    } else {
        this.myValue = value;
    }
}

または、値が適切に設定されていない場合は、ゲッターがデフォルト値を返すようにします。

public String getMyValue() {
    if(this.myvalue == null || this.myvalue.isEmpty()){
        return "N/A";
    }    
    return this.myValue;
}

遅延読み込みの場合、ゲッターでメンバーを変更しても問題ないと思いますが、次のようにします。

public String getMyValue() {
    if (this.myvalue == null) {
        this.myvalue = loadMyValue();
    }    
    return this.myValue;
}
38

いいえ。ここでは2つのことを行っています。取得と設定。

11
Mark W

はい。それは悪い習慣です。

どうして?

値が設定されている場合(コンストラクターまたはセッターメソッドで)、getterメソッドが呼び出されたときではなく、検証する必要があります。このためにprivatevalidate*メソッドを作成することも良い考えです。

private boolean validateThisValue(String a) {
     return this.myValue != null && !this.myValue.isEmpty();
}

public void setThisValue(String a) {
    if (validateThisValue(a)) {
        this.myValue = a;
    } 
    else {
        // do something else
        // in this example will be
        this.myValue = "N/A";
    }
}

また、getterメソッドでは、オブジェクトの状態を変更しないでください。私はいくつかのプロジェクトに取り組んできましたが、ゲッターはしばしばconst: "このメソッドは内部状態を変更できません"にする必要があります。

少なくとも、物事を複雑にしたくない場合は、getterメソッドで、change内部状態ではなくreturn"N/A"を実行し、myValueから"N/A"

10
hqt

私は通常、特定のgetterを定義します。

元のgetterを変更しないでください:

 public String getMyValue(){
     return this.myValue
 }

そして、特定のgetterを作成します:

public String getMyValueFormatted(){

    if(this.myvalue == null || this.myvalue.isEmpty()){
       return "N/A";
    }else{
       return this.myValue;
    }
 }
6
Rodrigo

this.myValue = "N/A"を初期化する方が良いと思います。その後、setMyValueを呼び出すと、ビジネスの状況に応じてthis.myValueが変更されます。
getMyValueはいかなる方法でもthis.myValueを変更してはなりません。特定の値を返す必要がある場合は、this.myValueを変更せずに、その値( "N/A"など)を返す必要があります。ゲッターはメンバーの値を変更してはなりません。

5
George D

セッターメソッド内でオブジェクトを変更するのではなく、ゲッターメソッド内でオブジェクトを変更する必要がある理由を説明しない限り、これは悪い習慣だと思います。
何らかの理由でこれができないと思いますか?詳しく教えていただけますか?

4
ramesh

セッターは検証の一部として変更できますが、ゲッターは値を返し、呼び出し元が検証を実行できるようにする必要があります。 do検証する場合は、どのように文書化する必要があります。

4
Bizmarck

好きなことをしてください。結局のところ、ゲッターとセッターは単なる別のパブリックメソッドです。他の名前を使用することもできます。

ただし、Springのようなフレームワークを使用する場合は、それらの標準名を使用する必要があり、カスタムコードをその中に入れないでください。

4
Mawia

セッターメソッドをより適切に変更して、値がnullまたは空の場合、_N/A_が属性に割り当てられるようにします。したがって、クラス内の他のメソッド(v.g. toString())で属性を使用すると、目的の値がそこにあります。

または、設定されている値が正しくない場合に例外を起動するようにsetterメソッドを変更します。これにより、プログラマーは値を設定する前に処理を改善する必要があります。

それ以外は大丈夫です。

4
SJuan76

絶対にそうです、それは悪い習慣です。

ネットワークを介してサードパーティ(リモーティング、COMなど)と通信すると、ラウンドトリップが増加し、アプリケーションのパフォーマンスが向上するとします。

3
xPridex

これは実際には、get()メソッドで適用するコントラクトに大きく依存します。契約による設計の規則によれば、呼び出し元は前提条件が満たされていることを確認する必要があり(つまり、setterメソッドで検証を行うことは実際には悪い設計であることが多い)、呼び出し先(それが正しい英語の用語であるかどうかはわかりません)つまり、呼び出されたもの)は、ポスト条件が満たされていることを確認します。

Get()メソッドがオブジェクトを変更できないようにコントラクトを定義すると、独自のコントラクトが破られます。次のような方法を実装することを考えてください

public isValid() {
    return (this.myvalue == null || this.myvalue.isEmpty());
}

このアプローチの利点は、get()の戻り値が「N/A」であるかどうかを確認する必要がないことです。これは、set()を呼び出す前に呼び出して、オブジェクトに不正な値を挿入していないことを検証することもできます。

デフォルト値を設定する場合は、初期化中に行う必要があります。

3
Lucas Hoepner

ゲッターの状態変化は、ぶら下がっている犯罪であるべきです。つまり、クライアントコードは、ゲッターとセッターにアクセスする順序に注意する必要があり、これを行うには、実装に関する知識が必要です。ゲッターを任意の順序で呼び出すことができ、それでも同じ結果を得ることができるはずです。セッターがオブジェクトの現在の状態に応じて入力値を変更すると、関連する問題が発生します。

3
Kevin Whitefoot

この目的のために、いくつかの値ホルダーを使用できます。グアバライブラリのオプションクラスのように。

2