これは、実際の意味に依存a
、b
とgetProduct
。
ゲッターの目的は、オブジェクトのインターフェースを同じに保ちながら、実際の実装を変更できるようにすることです。たとえば、ある日がにgetA
なったreturn a + 1;
場合、変更はゲッターにローカライズされます。
実際のシナリオのケースは、ゲッターに関連付けられたコンストラクターを通じて割り当てられる定数のバッキングフィールドよりも複雑な場合があります。たとえば、フィールドの値は、コードの元のバージョンのデータベースから計算またはロードできます。次のバージョンでは、パフォーマンスを最適化するためにキャッシュが追加される可能性があります。getProduct
計算されたバージョンを引き続き使用する場合、キャッシングのメリットはありません(または、メンテナーが同じ変更を2回行います)。
それはのための完璧な感覚になり場合はgetProduct
使用をa
してb
、直接、それらを使用しています。それ以外の場合は、ゲッターを使用して、後でメンテナンスの問題を防ぎます。
ゲッターを使用する例:
class Product {
public:
Product(ProductId id) : {
price = Money.fromCents(
data.findProductById(id).price,
environment.currentCurrency
)
}
Money getPrice() {
return price;
}
Money getPriceWithRebate() {
return getPrice().applyRebate(rebate); // ← Using a getter instead of a field.
}
private:
Money price;
}
現時点では、ゲッターにはビジネスロジックは含まれていませんが、オブジェクトの初期化時にデータベースの作業を回避するために、コンストラクターのロジックがゲッターに移行されることは除外されません。
class Product {
public:
Product(ProductId id) : id(id) { }
Money getPrice() {
return Money.fromCents(
data.findProductById(id).price,
environment.currentCurrency
)
}
Money getPriceWithRebate() {
return getPrice().applyRebate(rebate);
}
private:
const ProductId id;
}
後で、キャッシュを追加することができます(C#では、を使用Lazy<T>
してコードを短く簡単にします。C++に同等のものがあるかどうかはわかりません)。
class Product {
public:
Product(ProductId id) : id(id) { }
Money getPrice() {
if (priceCache == NULL) {
priceCache = Money.fromCents(
data.findProductById(id).price,
environment.currentCurrency
)
return priceCache;
}
Money getPriceWithRebate() {
return getPrice().applyRebate(rebate);
}
private:
const ProductId id;
Money priceCache;
}
どちらの変更もゲッターとバッキングフィールドに焦点を合わせており、残りのコードは影響を受けていません。代わりに、でゲッターの代わりにフィールドを使用していた場合は、getPriceWithRebate
そこにも変更を反映する必要があります。
おそらくプライベートフィールドを使用する例:
class Product {
public:
Product(ProductId id) : id(id) { }
ProductId getId() const { return id; }
Money getPrice() {
return Money.fromCents(
data.findProductById(id).price, // ← Accessing `id` directly.
environment.currentCurrency
)
}
private:
const ProductId id;
}
ゲッターは簡単です。これはreadonly
、将来変更されることのない定数(C#に類似)フィールドの直接表現です。チャンスは、IDゲッターが計算値になることはありません。そのため、シンプルにして、フィールドに直接アクセスします。
もう1つの利点は、getId
(前のコードのように)外部で使用されていないようであれば、将来削除される可能性があることです。
const
:私はそれはコンパイラがgetId
とにかく呼び出しをインライン化し、それがどちらの方向にも変更を加えることができることを意味すると仮定します。(そうでない場合、ゲッターを使用する理由に完全に同意します。)プロパティ構文を提供する言語では、バッキングフィールドではなくプロパティを直接使用しない理由はさらに少なくなります。