गेटर्स और सेटर्स का होना अपने आप में इनकैप्सुलेशन को तोड़ना नहीं है। क्या होता है ब्रेक इनकैप्सुलेशन स्वचालित रूप से प्रत्येक डेटा सदस्य (हर क्षेत्र , जावा लिंगो में) के लिए एक गेट्टर और एक सेटर जोड़ रहा है, बिना किसी विचार के। जबकि यह सभी डेटा सदस्यों को सार्वजनिक करने से बेहतर है, यह केवल एक छोटा कदम है।
एनकैप्सुलेशन की बात यह नहीं है कि आपको ऑब्जेक्ट के बाहर से ऑब्जेक्ट की स्थिति को जानने या बदलने में सक्षम नहीं होना चाहिए, लेकिन यह करने के लिए आपके पास एक उचित नीति होनी चाहिए ।
कुछ डेटा सदस्य ऑब्जेक्ट के लिए पूरी तरह से आंतरिक हो सकते हैं, और इसमें न तो गेटर्स होना चाहिए और न ही बसना चाहिए।
कुछ डेटा सदस्यों को केवल-पढ़ा जाना चाहिए, इसलिए उन्हें गेटर्स की आवश्यकता हो सकती है लेकिन बसने वालों की नहीं।
कुछ डेटा सदस्यों को एक दूसरे के अनुरूप रखने की आवश्यकता हो सकती है। ऐसे मामले में आप प्रत्येक के लिए एक सेटर प्रदान नहीं करेंगे, लेकिन एक ही समय में उन्हें सेट करने के लिए एक एकल विधि, ताकि आप स्थिरता के लिए मूल्यों की जांच कर सकें।
कुछ डेटा सदस्यों को केवल एक निश्चित तरीके से बदलने की आवश्यकता हो सकती है, जैसे कि एक निश्चित राशि द्वारा बढ़ा या घटाया गया। इस मामले में, आप एक सेटर के बजाय एक increment()
और / या decrement()
विधि प्रदान करेंगे ।
फिर भी अन्य लोगों को वास्तव में पढ़ने-लिखने की आवश्यकता हो सकती है, और इसमें एक गेट्टर और एक सेटर दोनों होंगे।
के एक उदाहरण पर विचार करें class Person
। मान लीजिए कि किसी व्यक्ति का नाम, सामाजिक सुरक्षा संख्या और आयु है। मान लीजिए कि हम लोगों को कभी भी अपना नाम या सामाजिक सुरक्षा संख्या बदलने की अनुमति नहीं देते हैं। हालांकि, व्यक्ति की उम्र हर साल 1 बढ़ाई जानी चाहिए। इस स्थिति में, आप एक निर्माता प्रदान करेंगे जो नाम और SSN को दिए गए मानों को इनिशियलाइज़ करेगा, और जो 0. की उम्र को इनिशियलाइज़ करेगा। आप एक विधि भी प्रदान incrementAge()
करेंगे, जिससे आयु में 1. वृद्धि होगी। आप यह भी प्रदान करेंगे। तीनों के लिए गेटर्स। इस मामले में किसी भी निपटान की आवश्यकता नहीं है।
इस डिजाइन में आप ऑब्जेक्ट की स्थिति को कक्षा के बाहर से निरीक्षण करने की अनुमति देते हैं, और आप इसे कक्षा के बाहर से बदलने की अनुमति देते हैं। हालांकि, आप राज्य को मनमाने ढंग से बदलने की अनुमति नहीं देते हैं। एक नीति है, जो प्रभावी रूप से बताती है कि नाम और एसएसएन को बिल्कुल भी नहीं बदला जा सकता है, और यह कि एक बार में 1 वर्ष की उम्र बढ़ाई जा सकती है।
अब मान लीजिए कि एक व्यक्ति का वेतन भी है। और लोग अपनी इच्छानुसार नौकरियों को बदल सकते हैं, जिसका अर्थ है कि उनका वेतन भी बदल जाएगा। इस स्थिति को मॉडल करने के लिए हमारे पास कोई और तरीका नहीं है बल्कि एक setSalary()
विधि प्रदान करने के लिए है ! वसीयत में बदला जाने वाला वेतन इस मामले में पूरी तरह से उचित नीति है।
वैसे, अपने उदाहरण में, मैं कक्षा देना होगा और तरीकों के बजाय और । तब आप अभी भी encapsulation होगा।Fridge
putCheese()
takeCheese()
get_cheese()
set_cheese()
public class Fridge {
private List objects;
private Date warranty;
/** How the warranty is stored internally is a detail. */
public Fridge( Date warranty ) {
// The Fridge can set its internal warranty, but it is not re-exposed.
setWarranty( warranty );
}
/** Doesn't expose how the fridge knows it is empty. */
public boolean isEmpty() {
return getObjects().isEmpty();
}
/** When the fridge has no more room... */
public boolean isFull() {
}
/** Answers whether the given object will fit. */
public boolean canStore( Object o ) {
boolean result = false;
// Clients may not ask how much room remains in the fridge.
if( o instanceof PhysicalObject ) {
PhysicalObject po = (PhysicalObject)o;
// How the fridge determines its remaining usable volume is a detail.
// How a physical object determines whether it fits within a specified
// volume is also a detail.
result = po.isEnclosedBy( getUsableVolume() );
}
return result;
}
/** Doesn't expose how the fridge knows its warranty has expired. */
public boolean isPastWarranty() {
return getWarranty().before( new Date() );
}
/** Doesn't expose how objects are stored in the fridge. */
public synchronized void store( Object o ) {
validateExpiration( o );
// Can the object fit?
if( canStore( o ) ) {
getObjects().add( o );
}
else {
throw FridgeFullException( o );
}
}
/** Doesn't expose how objects are removed from the fridge. */
public synchronized void remove( Object o ) {
if( !getObjects().contains( o ) ) {
throw new ObjectNotFoundException( o );
}
getObjects().remove( o );
validateExpiration( o );
}
/** Lazily initialized list, an implementation detail. */
private synchronized List getObjects() {
if( this.list == null ) { this.list = new List(); }
return this.list;
}
/** How object expiration is determined is also a detail. */
private void validateExpiration( Object o ) {
// Objects can answer whether they have gone past a given
// expiration date. How each object "knows" it has expired
// is a detail. The Fridge might use a scanner and
// items might have embedded RFID chips. It's a detail hidden
// by proper encapsulation.
if( o implements Expires && ((Expires)o).expiresBefore( today ) ) {
throw new ExpiredObjectException( o );
}
}
/** This creates a copy of the warranty for immutability purposes. */
private void setWarranty( Date warranty ) {
assert warranty != null;
this.warranty = new Date( warranty.getTime() )
}
}
Getters and setters are often criticized as being not proper OO
- प्रशस्ति पत्र, कृपया।