क्या किसी विधि का नाम बदलना एनकैप्सुलेशन को संरक्षित कर सकता है?


9

मैं इस पृष्ठ को पढ़ रहा था , जब गेटर्स / सेटर उचित हैं, और ओपी ने निम्नलिखित कोड नमूना दिया था:

class Fridge
{
     int cheese;

     void set_cheese(int _cheese) { cheese = _cheese; }
     int get_cheese() { return cheese; }
 }

void go_shopping(Fridge fridge)
{
     fridge.set_cheese(fridge.get_cheese() + 5);        
}

स्वीकार किए जाते हैं जवाब कहता है:

वैसे, अपने उदाहरण में, मैं कक्षा देना होगा और तरीकों के बजाय और । तब आप अभी भी encapsulation होगा।FridgeputCheese()takeCheese()get_cheese()set_cheese()

एन्कैप्सुलेशन कैसे प्राप्त किया जाता है इसे प्राप्त / सेट से बदलकर putCheese()/ takeCheese()आप स्पष्ट रूप से मूल्य प्राप्त कर रहे हैं / सेट कर रहे हैं, तो बस इसे पाने / सेट करने के लिए क्यों न छोड़ें?

एक ही उत्तर में यह भी कहा गया है:

गेटर्स और सेटर्स का होना अपने आप में इनकैप्सुलेशन को तोड़ना नहीं है। क्या होता है ब्रेक इनकैप्सुलेशन स्वचालित रूप से प्रत्येक डेटा सदस्य के लिए एक गेटटर और एक सेटर जोड़ रहा है (प्रत्येक क्षेत्र, जावा लिंगो में), बिना किसी विचार के।

इस मामले में, हमारे पास केवल एक चर है, cheeseऔर आप पनीर को फ्रिज में ले जाना और वापस करना चाह सकते हैं, इसलिए इस मामले में एक गेट / सेट जोड़ी उचित है।


7
putCheeseफ्रिज में पनीर जोड़ देगा, और takeCheeseइसे हटा देगा - ये (उच्च स्तर) डोमेन-ओरिएंटेड एब्स्ट्रक्शन हैं, ऑब्जेक्ट फ़ील्ड गेटर्स एंड सेटर्स (जो (निम्न-स्तरीय) कंप्यूटर प्रोग्रामिंग एब्स्ट्रक्शन हैं) के बजाय।
एरिक Eidt

जवाबों:


17

मेरी समझ है कि आप मुद्दे को भूल रहे हें। यह नहीं कह रहा है कि आपको सेटर और गेट्टर का नाम बदलना चाहिए, लेकिन उन तरीकों के लिए जो फ्रिज से आइटम जोड़ते और हटाते हैं। अर्थात

public class Fridge
{
    private int numberOfCheeseSlices;

    public void AddCheeseSlices(int n)
    {
         if(n < 0) { 
             throw new Exception("you cant add negative cheese!");
         }
         if(numberOfCheeseSlices + n > this.capacityOfFridge) { 
             throw new Exception("TOO MUCH CHEESE!!");
         }
         ..etc
         this.numberOfCheeseSlices += n;
    }
}

अब प्राइवेट वेरिएबल एनकैप्सुलेटेड है। मैं बस इसे अपनी इच्छानुसार किसी भी चीज़ के लिए सेट नहीं कर सकता, मैं केवल विधियों का उपयोग करके फ्रिज से पनीर के स्लाइस को जोड़ और हटा सकता हूं, जो बदले में यह सुनिश्चित करता है कि जो भी पनीर व्यवसाय तर्क नियम मैं चाहता हूं उसे लागू किया जाए।


2
ठीक है, लेकिन आप अभी भी इसे छोड़ सकते हैं क्योंकि setCheese()सेटर में वही तर्क है। मेरे लिए वैसे भी, आप इस तथ्य को छिपाने की कोशिश कर रहे हैं कि आप विधि का नाम बदलकर एक सेटर का उपयोग कर रहे हैं, लेकिन आपका स्पष्ट रूप से कुछ प्राप्त करने / स्थापित करने के लिए।
क्वीन्सवेटलाना

21
@QueenSvetlana यह कोई सेटर नहीं है। यह एक ऑपरेशन है। आप फ्रिज को "यहां एक और पनीर," बता रहे हैं और इसे अपने आंतरिक, समझाया पनीर की गिनती में जोड़ रहे हैं। एक सेटर कहेगा "अब आपके पास 5 चीज हैं।" ये कार्यात्मक रूप से अलग-अलग ऑपरेशन हैं, न कि अलग-अलग नाम।
एंट पी

1
आप इसे सेटशीज़ कह सकते हैं, लेकिन यह भ्रमित करने वाला होगा क्योंकि यह पनीर के मूल्य को निर्धारित नहीं करेगा।
इवान

6
नोट यहाँ एक पूर्णांक अतिप्रवाह बग है। यदि पहले से ही 0 से अधिक पनीर है, AddCheese(Integer.MAX_VALUE)तो विफल होना चाहिए, लेकिन नहीं होगा।
user253751 22

3
कि कुल मिलाकर ..etc सेक्शन में शामिल किया जाएगा
Ewan

5

परिभाषा के अनुसार हर एक बार गेटर्स और सेनेटर्स इनकैप्सुलेशन को तोड़ते हैं । क्या हो सकता है तर्क दिया जा है कि कभी कभी हम चाहते हैं कि क्या करने की जरूरत है। उस रास्ते से, यहाँ मेरे जवाब हैं:

एन्कैप्सुलेशन कैसे प्राप्त किया जाता है इसे गेट / सेट से पुसी () / टेकचेज़ () में बदलकर संरक्षित किया जाता है।

अंतर शब्दार्थ में है, अर्थात आप जो लिखते हैं उसका अर्थ है। एनकैप्सुलेशन केवल सुरक्षा के बारे में नहीं है, बल्कि आंतरिक स्थिति को छिपाना है। आंतरिक स्थिति को बाहर भी नहीं जाना चाहिए, इसके बजाय ऑब्जेक्ट को उस राज्य में हेरफेर / उपयोग करने के लिए व्यावसायिक-प्रासंगिक तरीकों (कभी-कभी "व्यवहार" के रूप में संदर्भित) की पेशकश करने की उम्मीद है।

तो getऔर setतकनीकी शब्दों रहे हैं और, "फ्रिज" डोमेन के साथ कुछ नहीं करना है, जबकि लगते हैं putऔर takeवास्तव में कुछ मतलब हो सकता है।

हालांकि , चाहे putया takeबनाने के वास्तविक भावना अभी भी आवश्यकताओं पर निर्भर करता है और निष्पक्ष न्याय नहीं किया जा सकता है। अगला बिंदु देखें:

इस मामले में, हमारे पास केवल एक चर, पनीर है, और आप पनीर को फ्रिज में ले जाना और वापस करना चाह सकते हैं, इसलिए इस मामले में एक जोड़ी / सेट जोड़ी उचित है।

यह अधिक संदर्भ के बिना उद्देश्यपूर्ण रूप से निर्धारित नहीं किया जा सकता है। आपके उदाहरण में एक go_shopping()विधि कहीं और है। यदि ऐसा है Fridgeतो इसके लिए, इसकी आवश्यकता नहीं है getया set, इसकी आवश्यकता क्या है Fridge.go_shopping()। इस तरह से आपके पास एक ऐसा तरीका है जो आवश्यकताओं से प्राप्त होता है, सभी "डेटा" जो कि इसकी आवश्यकता है, स्थानीय है और आपके पास बस एक पतले पर्दा डेटा संरचना के बजाय वास्तविक व्यवहार है

याद रखें, आप एक सामान्य, पुन: प्रयोज्य निर्माण नहीं कर रहे हैं Fridge। आप Fridgeअपनी आवश्यकताओं के लिए ही निर्माण कर रहे हैं । किसी भी प्रयास को खर्च करने से अधिक यह वास्तव में बेकार है।


10
Getters and setters break encapsulation every single time- यह मेरे स्वाद के लिए बहुत दृढ़ता से शब्द है। तरीके (गेटर्स और सेटर सहित) का एक ही उद्देश्य है कि एक संगीत समारोह में गेट्स करते हैं: वे व्यवस्थित रूप से प्रवेश और स्थल से बाहर निकलने की अनुमति देते हैं।
रॉबर्ट हार्वे

8
"गेटर्स एंड सेटर्स हर एक बार, परिभाषा के अनुसार इनकैप्सुलेशन को तोड़ते हैं" - किस परिभाषा से? मेरा भी इसके साथ एक मुद्दा है, क्योंकि गेटर्स और सेटर किसी भी अन्य सार्वजनिक सदस्य के रूप में सार्वजनिक इंटरफ़ेस का हिस्सा हैं; वे केवल कैप्सूलीकरण तोड़ने अगर वे कार्यान्वयन विवरण है कि आंतरिक माना जाता बेनकाब डिजाइन द्वारा (यह है कि, प्रोग्रामर (या एक टीम) के एक निर्णय से)। तथ्य यह है कि गेटर्स और सेटर को अक्सर बेतरतीब ढंग से जोड़ा जाता है, युग्मन नियंत्रण के बाद एक और बात होती है, पूरी तरह से एक और मामला है।
फिलिप मिलोवानोविक

2
@ FilipMilovanović मेला बिंदु। जैसा कि मैंने उत्तर में उल्लेख किया है, "इनकैप्सुलेशन" का उपयोग ऑब्जेक्ट इंटर्नल्स (== ऑब्जेक्ट स्टेट == उदाहरण चर) को छिपाने के लिए किया जाता है । गेटर्स और सेटर ऑब्जेक्ट इंटर्नल्स प्रकाशित करते हैं। इसलिए इन परिभाषाओं के अनुसार वे निरंतर संघर्ष में हैं। अब, क्या कभी-कभी हमें एनकैप्सुलेशन को तोड़ने की आवश्यकता होती है, एक अलग मामला है, जिसे अलग से संभाला जाना चाहिए। स्पष्ट होने के लिए, यह कहते हुए कि बसने वाले / पाने वाले हमेशा अतिक्रमण को तोड़ते हैं, मैं यह नहीं कह रहा कि यह हमेशा "गलत" है, अगर यह मदद करता है।
रॉबर्ट ब्रुटिगम

5
गेटर्स और सेटर "हमेशा के लिए इनकैप्सुलेशन को नहीं तोड़ते हैं"। गेटर्स और सेटर प्रायः सीधे नीचे के सदस्यों को संदर्भित नहीं करते हैं, कुछ प्रकार के ऑपरेशन करते हैं, या केवल विशेष रूप से परिभाषित होते हैं, आपके पास केवल एक गेटटर हो सकता है या केवल एक सेटर हो सकता है। यह एन्कैप्सुलेशन को तोड़ता है जब गेटर्स और सेटर सदस्य पहुंच से अधिक कुछ नहीं करते हैं और दोनों एक ही फ़ील्ड के लिए परिभाषित होते हैं। यहां तक ​​कि पुस्तकालय के रख-रखाव के लिए यह आवश्यक हो सकता है जो आंतरिक परिवर्तनों के साथ एबीआई / एपीआई को तोड़ना नहीं चाहते हैं और ग्राहक पुनर्मूल्यांकन से बचते हैं।
whn

4
ठीक है, गेटर्स और सेटर केवल 99% समय का एनकैप्सुलेशन तोड़ते हैं। खुश? और, एन्कैप्सुलेटेड ऑब्जेक्ट के प्रकार को उजागर करके , वे निश्चित रूप से एनकैप्सुलेशन को तोड़ते हैं। एक बार आपके पास public int getFoo()यह लगभग असंभव है, व्यवहार में, दूसरे प्रकार में बदलने के लिए।
user949300

3

लगभग यह सब एनकैप्सुलेशन की एक बुनियादी गलतफहमी को दर्शाता है, और यह कैसे लागू होता है।

प्रारंभिक प्रतिक्रिया जिसे आप एनकैप्सुलेशन तोड़ रहे थे, वह सिर्फ गलत है। आपके आवेदन में वेतन वृद्धि / वेतन वृद्धि या जोड़ने / हटाने के बजाय फ्रिज में पनीर के मूल्य को निर्धारित करने की आवश्यकता हो सकती है। इसके अलावा, यह शब्दार्थ नहीं है, इससे कोई फर्क नहीं पड़ता कि आप इसे क्या कहते हैं, यदि आपको उन विशेषताओं को एक्सेस करने और / या बदलने की आवश्यकता है जो आप उन्हें प्रदान करके इनकैप्सुलेशन को नहीं तोड़ते हैं। अंत में, एनकैप्सुलेशन वास्तव में "छिपाना" के बारे में नहीं है, यह राज्य और मूल्यों तक पहुंच को नियंत्रित करने के बारे में है जो कि कक्षा के बाहर सार्वजनिक या हेरफेर करने की आवश्यकता नहीं है, जबकि इसे उन लोगों को प्रदान करना चाहिए जो आंतरिक रूप से उपलब्ध कराए गए कार्य को करना और प्रदर्शन करना चाहिए।

जब कोई मान प्राप्त करने या सेट करने की वैध आवश्यकता होती है, तो एक गेट्टर या सेटर इनकैप्सुलेशन को नहीं तोड़ता है। यही कारण है कि तरीकों को सार्वजनिक किया जा सकता है।

एनकैप्सुलेशन डेटा रखने के बारे में है और विधियाँ जो उस डेटा को सीधे एक तार्किक स्थान, कक्षा में एक साथ संशोधित करती हैं।

इस विशेष मामले में, स्पष्ट रूप से आवेदन में पनीर के मूल्य को बदलने की आवश्यकता है। यह कैसे किया जाता है, इसके बावजूद, जब तक आप ऑब्जेक्ट ओरिएंटेड स्टाइल का पालन नहीं कर रहे हैं, तब तक जब तक आप क्लास में इनकैप्सुलेटेड हैं, तब तक गेट / सेट या ऐड / रिमूव के जरिए।

स्पष्टीकरण के लिए, मैं इस बात का उदाहरण दूंगा कि विधि नाम या तार्किक निष्पादन की परवाह किए बिना पहुँच प्रदान करके कैसे अतिक्रमण को तोड़ा जाता है।

मान लें कि आपके फ्रिज में एक "जीवनकाल" है, फ्रिज से पहले बस कई टिक टिक अब चालू नहीं है (तर्क के लिए, फ्रिज की मरम्मत नहीं की जा सकती)। तार्किक रूप से कोई तरीका नहीं है कि एक उपयोगकर्ता (या आपके बाकी एप्लिकेशन) को इस मूल्य को बदलने में सक्षम होना चाहिए। यह निजी होना चाहिए। यह केवल एक अलग सार्वजनिक विशेषता के माध्यम से दिखाई देगा, जिसे "isWorking" के रूप में जाना जाता है। जब जीवनकाल समाप्त हो जाता है, आंतरिक रूप से फ्रिज सेट झूठी के लिए काम कर रहा है।

जीवन भर की गणना के निष्पादन और इसके आइसिंगिंग स्विच को उतारने से फ्रिज में सभी आंतरिक होते हैं, बाहर कुछ भी नहीं हो सकता है / प्रक्रिया को प्रभावित करने में सक्षम होना चाहिए। isWorking केवल दिखाई देनी चाहिए, इस प्रकार एक गेटक इनकैप्सुलेशन को नहीं तोड़ता है। हालाँकि जीवनकाल की प्रक्रिया के तत्वों के लिए एक्सेसर्स जोड़ने से आपका एनकैप्सुलेशन टूट जाएगा।

ज्यादातर चीजों की तरह, एनकैप्सुलेशन की परिभाषा शाब्दिक नहीं है, यह सापेक्ष है। क्या आपको कक्षा के बाहर एक्स को देखने में सक्षम होना चाहिए? क्या आपको वाई बदलने में सक्षम होना चाहिए? क्या वह सब कुछ है जो इस वर्ग में आपकी वस्तु पर लागू होता है या कार्यक्षमता कई वर्गों में फैली हुई है?


आइए इसे व्यावहारिक रूप से देखें। आप कह रहे हैं कि यदि कोड का इरादा उस तरीके से है, या यदि कोई "वैध" कारण है, तो एनकैप्सुलेशन नहीं टूटा है । मूल रूप से इसका मतलब है कि हम कभी नहीं कह सकते हैं कि एनकैप्सुलेशन टूट गया है, क्योंकि डेवलपर को केवल उस तरह से "इरादा" कहना है, या "वैध" कारण था। तो यह परिभाषा मूल रूप से बेकार है, है ना?
रॉबर्ट ब्रुटिगम

नहीं, मैं कहता हूं कि केवल पहुंच प्रदान करने से एनकैप्सुलेशन नहीं टूटा है। और इससे कोई लेना-देना नहीं है कि एक प्रोग्रामर क्या कहता है, लेकिन एप्लिकेशन की क्या जरूरतें हैं। एक एप्लिकेशन को वस्तुओं में हेरफेर करने के लिए एक्सेस की आवश्यकता है, इनकैप्सुलेशन एक्सेस को नियंत्रित करने के बारे में है। किसी एप्लिकेशन को किसी ऑब्जेक्ट की विशेषता "सेट" करने की आवश्यकता हो सकती है, लेकिन उस "सेट" ऑपरेशन को करने के लिए आवश्यक तर्क और गणना को ऑब्जेक्ट क्लास में समझाया जाना चाहिए।
user343330

मुझे लगता है कि यह वह जगह है जहां हम मौलिक रूप से भिन्न होते हैं, आप कहते हैं: "किसी एप्लिकेशन को किसी ऑब्जेक्ट की विशेषता" सेट "करने की आवश्यकता हो सकती है ..."। मुझे ऐसा नहीं लगता। एक डिज़ाइन चुनना जिसमें एक विशेषता स्थापित करना या प्राप्त करना शामिल है, डेवलपर पर निर्भर है। यह एक विकल्प है! कुछ को कोड करने के बहुत सारे तरीके हैं, जिनमें से सभी में चर मान प्राप्त करना या स्थापित करना शामिल नहीं है।
रॉबर्ट ब्रुटिगम

हो सकता है ... आमतौर पर डिजाइन एक जरूरत को पूरा करने के आसपास आधारित होता है, चाहे प्रोग्रामर द्वारा चुना गया हो या व्यावसायिक वातावरण पर आधारित हो। किसी भी स्थिति में, यदि एप्लिकेशन को किसी ऑब्जेक्ट का एक हिस्सा हेरफेर करने की मूलभूत आवश्यकता है, तो आपको उस कार्यक्षमता को किसी तरह से सुलभ बनाना होगा। काम करने के लिए एक प्रवेश बिंदु प्रदान करना एनकैप्सुलेशन को तोड़ना नहीं है। एक बिक्री एप्लिकेशन लें। कुछ बिंदु पर आपके लेन-देन को कर की गणना करनी चाहिए, यह करते हुए कि लेन-देन ऑब्जेक्ट में इसे
गुप्त रखा

उनकी सादगी के कारण सेटर्स खराब उदाहरण हैं, एक फ़ंक्शन के संदर्भ में सोचें जो कि कहीं अधिक काम करता है जिसके परिणामस्वरूप ऑब्जेक्ट विशेषता को अद्यतन किया जा रहा है बनाम काम करने वाले वर्ग के बाहर कुछ और फिर ऑब्जेक्ट कहलाता है। x। उपयुक्त पहुंच प्रदान करते हुए पहला अच्छा एनकैप्सुलेशन है, दूसरा नहीं है। प्राप्तकर्ताओं के लिए, क्या एप्लिकेशन को किसी वस्तु के उस टुकड़े को जानने के लिए कुछ और करने की आवश्यकता है जो ऑब्जेक्ट क्लास में शामिल नहीं हो सकता है? यदि हां, तो इसे उजागर करने से आपका एनकैप्सुलेशन नहीं टूटेगा। यदि नहीं, तो इसे ऑब्जेक्ट क्लास में
एनकैप्सुलेट करें

1

यह सिर्फ एक विधि का नाम नहीं है। दो तरीके अलग-अलग कार्य करते हैं।

(चित्र अपने दिमाग में)

get_cheese और set_cheese पनीर को उजागर करता है। putCheese () और takeCheese () पनीर को छिपाकर रखता है और इसे प्रबंधित करने का ध्यान रखता है और उपयोगकर्ता को इसे संभालने का एक तरीका देता है। प्रेक्षक पनीर को नहीं देखता है, वह केवल उसे हेरफेर करने के दो तरीके देखता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.