Bu gerçek anlamını bağlıdır a
, b
ve getProduct
.
Alıcıların amacı, nesnenin arayüzünü aynı tutarken gerçek uygulamayı değiştirebilmektir. Bir gün, Örneğin, getA
olur return a + 1;
, değişim bir gaz giderici lokalize olur.
Gerçek senaryo vakaları bazen bir alıcı ile ilişkili bir kurucu aracılığıyla atanan sabit bir destek alanından daha karmaşıktır. Örneğin, alanın değeri hesaplanabilir veya kodun orijinal sürümündeki bir veritabanından yüklenebilir. Bir sonraki versiyonda, performansı optimize etmek için önbellekleme eklenebilir. Eğer getProduct
bilgisayarlı sürümünü kullanmaya devam eder, bu önbelleğe yarar olmaz (veya sürdürme iki defa aynı değişikliği yapacağız).
Kullanmak ve doğrudan getProduct
kullanmak mantıklıysa , onları kullanın. Aksi takdirde, daha sonra bakım sorunlarını önlemek için alıcıları kullanın.a
b
Birinin alıcıları kullanacağı örnek:
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;
}
Şu an için, alıcı herhangi bir iş mantığı içermese de, nesneyi başlatırken veritabanı çalışması yapmaktan kaçınmak için yapıcıdaki mantığın alıcıya taşınacağı hariç tutulmamaktadır:
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;
}
Daha sonra, önbellekleme eklenebilir (C #, bir kullanacak Lazy<T>
, kodu kısa ve kolay hale getirme; C ++ 'da eşdeğer olup olmadığını bilmiyorum):
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;
}
Her iki değişiklik de alıcıya ve destek alanına odaklandı, kalan kod etkilenmedi. Bunun yerine, bir alıcı yerine bir alan kullansaydım getPriceWithRebate
, oradaki değişiklikleri de yansıtmalıydım.
Kişinin muhtemelen özel alanları kullanacağı örnek:
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;
}
Alıcı basittir: readonly
gelecekte değişmesi beklenmeyen bir sabit (C # 'a benzer ) alanın doğrudan bir temsilidir : Şansı vardır, ID alıcısı asla hesaplanan bir değer olmaz. Bu yüzden basit tutun ve alana doğrudan erişin.
Başka bir avantajı, getId
dışarıda kullanılmadığı anlaşılırsa gelecekte kaldırılabilmesidir (önceki kodda olduğu gibi).
const
: Derleyicinin birgetId
çağrıyı yine de arayacağı anlamına geliyor ve her iki yönde de değişiklik yapmanıza izin veriyor. (Aksi takdirde ben tam nedenlerle katılıyorum için . Kullanım getters) Ve özellik dizimi sağlıyoruz dilde, mülk ziyade doğrudan destek alanını kullanmamayı da azı nedenleri var.