यह के वास्तविक अर्थ की निर्भर करता है a
, b
और getProduct
।
गेटर्स का उद्देश्य ऑब्जेक्ट के इंटरफ़ेस को समान रखते हुए वास्तविक कार्यान्वयन को बदलने में सक्षम होना है। उदाहरण के लिए, यदि एक दिन, getA
बन जाता है return a + 1;
, तो परिवर्तन एक गटर के लिए स्थानीय होता है।
वास्तविक परिदृश्य के मामले कभी-कभी एक गेटर से जुड़े एक कंस्ट्रक्टर के माध्यम से सौंपे गए निरंतर समर्थन क्षेत्र की तुलना में अधिक जटिल होते हैं। उदाहरण के लिए, फ़ील्ड के मूल्य को कोड के मूल संस्करण में डेटाबेस से गणना या लोड किया जा सकता है। अगले संस्करण में, प्रदर्शन को अनुकूलित करने के लिए कैशिंग जोड़ा जा सकता है। यदि getProduct
गणना किए गए संस्करण का उपयोग करना जारी रखता है, तो यह कैशिंग (या अनुचर दो बार एक ही परिवर्तन करेगा) से लाभ नहीं होगा।
यदि यह 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;
}
बाद में, कैशिंग जोड़ा जा सकता है (सी # में, एक का उपयोग करेगा Lazy<T>
, कोड को छोटा और आसान बना देगा; मुझे नहीं पता कि क्या सी ++ में एक बराबर है):
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;
}
गेट्टर सीधा है: यह एक निरंतर (C # 's readonly
) क्षेत्र के समान प्रत्यक्ष प्रतिनिधित्व है , जिसे भविष्य में बदलने की उम्मीद नहीं है: संभावना है, आईडी गेट्टर कभी भी एक गणना मूल्य नहीं बनेगा। इसलिए इसे सरल रखें, और सीधे क्षेत्र तक पहुंचें।
एक और लाभ यह है कि getId
भविष्य में हटाया जा सकता है अगर ऐसा प्रतीत होता है कि इसका उपयोग बाहर नहीं किया गया है (जैसे कि कोड के पिछले टुकड़े में)।
const
: मेरा मानना है कि कंपाइलर का मतलबgetId
वैसे भी कॉल को इनलाइन करना होगा और यह आपको किसी भी दिशा में बदलाव करने की अनुमति देता है। (अन्यथा मैं गेटर्स का उपयोग करने के लिए आपके कारणों से पूरी तरह सहमत हूं ।) और ऐसी भाषाएं जो संपत्ति सिंटैक्स प्रदान करती हैं, सीधे समर्थन क्षेत्र के बजाय संपत्ति का उपयोग नहीं करने के और भी कम कारण हैं।