次の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つの表記に固執する必要がある、またはすべきでない理由と、この点に関するベストプラクティスは何ですか?
なぜゲッターとセッター/アクセサーを使用するのですか? の一般原則に加えて、例を挙げてそれに答えて、これがあなたの質問なので、内部的に使用クラスに焦点を当てようとします。
明確化のための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();
}
これで、クラス自体の内部でゲッターを使用する利点が明確になることを願っています。コードをリファクタリングする際の労力が減ります。しかし、それは価値がありますか?
たぶん、以前のタイプをもう使いたくないでしょう。おそらく、クラスをリファクタリングする手間は最小限です。 読みやすさという要素が適切に機能するかもしれません。クラスはどのように変更される可能性がありますか?将来的にゲッターに機能が含まれる可能性がありますか?私の会社には慣習がありますか?
これらの質問の回答はすべて特定のユースケースに依存するため、一般的な回答はありません。
とにかく、私は(私の経験から)リファクタリングが害を与えず、ほとんどの場合、より多くの利点をもたらすため、フィールドを直接使用することをお勧めします。あなたはよりクリーンなコードを持ち、コンセプトの奇妙な混合はないでしょう。わからない場合は、最もシンプルで読みやすいソリューションを実行してください。
答えは、ゲッター/セッターが単にフィールドを取得/設定するだけではない場合を無視しています。その場合、明らかにゲッター/セッターを常に使用したいでしょう。
最初にセマンティクスを確認してください。誰かがクラスをサブクラス化し、ゲッターを(誤って)オーバーライドして、インスタンス変数を返さないようにすることができます。この意味で、インスタンス変数の代わりにゲッターを使用することは、たとえ基底クラス自体であっても間違っています。
一方、サブクラス化を許可しない場合があります。