web-dev-qa-db-ja.com

クラスのコンテキスト内でのゲッター表記の使用法

次のJavaScriptコードを考えてみます。

_class MyClass {
   #myPrivateField;
   constructor() {
      #myPrivateField = new AnotherClass();
      this.theGetter.method1(); // or: this.#myPrivateField.method1(); 
      this.theGetter.method2(); // or: this.#myPrivateField.method2();
   }
   get theGetter() {
      return this.#myPrivateField;
   }
}
_

明らかに、theGetterの「getter」メソッドを呼び出すと、無視できるオーバーヘッドが発生するか、おそらくインライン化されます。クラス内では、ゲッターは "ダイレクトアクセス"表記(つまり、this.#myPrivateField.method1()など)で完全に置き換えることができます。

パフォーマンスのペナルティに関係なく、ソフトウェアエンジニアリングの観点から、クラスのコンテキスト内で他の表記よりも1つの表記に固執する必要がある、またはすべきでない理由と、この点に関するベストプラクティスは何ですか?

2
goodUser

なぜゲッターとセッター/アクセサーを使用するのですか? の一般原則に加えて、例を挙げてそれに答えて、これがあなたの質問なので、内部的に使用クラスに焦点を当てようとします。


明確化のための1つのこと:Javaには、 Coordinated Universal Time(UTC))に関する特定の時点を表す2つのクラスがあります どちらにも、ミリ秒単位の値を取得するメソッドがあります。つまり、 Date#getTime および Instant#toEpochMilli


Javaを使用する2つのバージョンのクラスを想像してください。

class Data {
    private Date date;

    public Date getDate() {
        return date;
    }

    public long getMillis() {
        return date.getTime();
    }
}
class Data {
    private Date date;

    public Date getDate() {
        return date;
    }

    public long getMillis() {
        return getDate().getTime();
    }
}

最初のバージョンはフィールドを直接使用し、2番目のバージョンはゲッターを使用することに注意してください。

ここで、dateのタイプをInstantに変更することを想像してください。したがって、次のようにバージョンを変更する必要があります。 最小限の変更で変更します。変更する最初のことは明らかにフィールド自体です。

    private Instant date;

変更する2番目のことはゲッターです。しかし、どうやって?新しいタイプを返すように変更するのか、それとも変換するのか?

    public Instant getDate() {
        return date;
    }
    public Date getDate() {
        return Date.fromInstant(date);
    }

ゲッターをどのように変更したかによって、ゲッターを使用するメソッドは次のように変わります。

    public long getMillis() {
        return getDate().toEpochMilli();
    }
    public long getMillis() {
        return getDate().getTime();
    }

ご覧のとおり、ゲッターを以前の型から新しい型に変換するように変更する場合、usingメソッドを変更する必要はまったくありません

フィールドに直接アクセスするメソッドのバージョンは、次のように変更する必要があります

    public long getMillis() {
        return date.toEpochMilli();
    }

これで、クラス自体の内部でゲッターを使用する利点が明確になることを願っています。コードをリファクタリングする際の労力が減ります。しかし、それは価値がありますか?

たぶん、以前のタイプをもう使いたくないでしょう。おそらく、クラスをリファクタリングする手間は最小限です。 読みやすさという要素が適切に機能するかもしれません。クラスはどのように変更される可能性がありますか?将来的にゲッターに機能が含まれる可能性がありますか?私の会社には慣習がありますか?

これらの質問の回答はすべて特定のユースケースに依存するため、一般的な回答はありません。

とにかく、私は(私の経験から)リファクタリングが害を与えず、ほとんどの場合、より多くの利点をもたらすため、フィールドを直接使用することをお勧めします。あなたはよりクリーンなコードを持ち、コンセプトの奇妙な混合はないでしょう。わからない場合は、最もシンプルで読みやすいソリューションを実行してください。


答えは、ゲッター/セッターが単にフィールドを取得/設定するだけではない場合を無視しています。その場合、明らかにゲッター/セッターを常に使用したいでしょう。

3
akuzminykh

最初にセマンティクスを確認してください。誰かがクラスをサブクラス化し、ゲッターを(誤って)オーバーライドして、インスタンス変数を返さないようにすることができます。この意味で、インスタンス変数の代わりにゲッターを使用することは、たとえ基底クラス自体であっても間違っています。

一方、サブクラス化を許可しない場合があります。

1
gnasher729