एनकैप्सुलेशन का एक उद्देश्य होता है, लेकिन इसका दुरुपयोग या दुरुपयोग भी किया जा सकता है।
एंड्रॉइड एपीआई की तरह कुछ पर विचार करें जिसमें दर्जनों (यदि सैकड़ों नहीं) क्षेत्रों के साथ कक्षाएं हैं। उन क्षेत्रों को एक्सपोज़ करने से एपीआई के उपभोक्ता को नेविगेट करने और उपयोग करने में मुश्किल होती है, साथ ही यह उपयोगकर्ता को यह गलत धारणा देता है कि वह उन क्षेत्रों के साथ जो चाहे कर सकता है जो कि उनका उपयोग करने के तरीके के साथ संघर्ष कर सकता है। अतिक्रमण इस मायने में महान है कि स्थिरता, उपयोगिता, पठनीयता और पागल बग से बचने के लिए।
दूसरी ओर, POD या सादे पुराने डेटा प्रकार, जैसे C / C ++ की एक संरचना जिसमें सभी क्षेत्र सार्वजनिक हैं, उपयोगी हो सकते हैं। लोनोक में @data एनोटेशन द्वारा उत्पन्न लोगों की तरह बेकार गेटर्स / सेटर करना "एनकैप्सुलेशन पैटर्न" रखने का एक तरीका है। जावा में "बेकार" गेटर्स / सेटर करने वाले कुछ कारणों में से एक यह है कि विधियां एक अनुबंध प्रदान करती हैं ।
जावा में, आपके पास इंटरफ़ेस में फ़ील्ड नहीं हो सकते हैं, इसलिए आप एक सामान्य संपत्ति निर्दिष्ट करने के लिए गेटर्स और सेटर का उपयोग करते हैं जो उस इंटरफ़ेस के सभी कार्यान्वयनकर्ताओं के पास है। कोटलिन या सी # जैसी अधिक हालिया भाषाओं में हम संपत्तियों की अवधारणा को उन क्षेत्रों के रूप में देखते हैं जिनके लिए आप एक सेटर और गटर की घोषणा कर सकते हैं। अंत में, बेकार गेटर्स / सेटर एक विरासत के अधिक होते हैं जो जावा के साथ रहना पड़ता है, जब तक कि ओरेकल इसके गुणों को जोड़ता नहीं है। उदाहरण के लिए, Kotlin, जो JetBrains द्वारा विकसित एक और JVM भाषा है, में डेटा वर्ग हैं जो मूल रूप से @data एनोटेशन लोम्बोक में करते हैं।
यहाँ भी कुछ उदाहरण हैं:
class DataClass
{
private int data;
public int getData() { return data; }
public void setData(int data) { this.data = data; }
}
यह इनकैप्सुलेशन का एक बुरा मामला है। गेटटर और सेटर प्रभावी रूप से बेकार हैं। एन्कैप्सुलेशन का उपयोग ज्यादातर इसलिए किया जाता है क्योंकि जावा जैसी भाषाओं में यह मानक है। वास्तव में मदद नहीं करता है, कोड बेस के पार स्थिरता बनाए रखने के अलावा।
class DataClass implements IDataInterface
{
private int data;
@Override public int getData() { return data; }
@Override public void setData(int data) { this.data = data; }
}
यह एनकैप्सुलेशन का एक अच्छा उदाहरण है। इस मामले में IDataInterface एक अनुबंध को लागू करने के लिए इनकैप्सुलेशन का उपयोग किया जाता है। इस उदाहरण में एनकैप्सुलेशन का उद्देश्य इस वर्ग के उपभोक्ता को इंटरफ़ेस द्वारा प्रदान की जाने वाली विधियों का उपयोग करना है। भले ही गेट्टर और सेटर कुछ भी फैंसी नहीं करते हैं, हमने अब डेटाक्लास और आईडीटाइंटरफेस के अन्य कार्यान्वयनकर्ताओं के बीच एक सामान्य विशेषता को परिभाषित किया है। इस प्रकार मेरे पास एक तरीका हो सकता है:
void doSomethingWithData(IDataInterface data) { data.setData(...); }
अब, जब मैं एनकैप्सुलेशन के बारे में बात कर रहा हूं तो मुझे लगता है कि सिंटैक्स समस्या को भी स्वीकार करना महत्वपूर्ण है। मैं अक्सर लोगों को सिंटैक्स के बारे में शिकायत करते देखता हूं जो एनकैप्सुलेशन के बजाय एनकैप्सुलेशन को लागू करने के लिए आवश्यक है। एक उदाहरण जो दिमाग में आता है वह केसी मुराटोरी का है (आप यहां उनके शेख को देख सकते हैं )।
मान लीजिए कि आपके पास एक खिलाड़ी वर्ग है जो एनकैप्सुलेशन का उपयोग करता है और 1 इकाई द्वारा अपनी स्थिति को स्थानांतरित करना चाहता है। कोड इस तरह दिखेगा:
player.setPosX(player.getPosX() + 1);
इनकैप्सुलेशन के बिना यह इस तरह दिखेगा:
player.posX++;
यहां उनका तर्क है कि एनकैप्सुलेशन बहुत अधिक टाइपिंग के साथ होता है, जिसमें कोई अतिरिक्त लाभ नहीं है और यह कई मामलों में सही हो सकता है, लेकिन कुछ को नोटिस करें। तर्क सिंटैक्स के खिलाफ है, न कि केवल एनकैप्सुलेशन। यहां तक कि सी जैसी भाषाओं में, जिनमें एनकैप्सुलेशन की अवधारणा का अभाव होता है, आप अक्सर '_' या 'माय' के साथ या इसके साथ जुड़े हुए स्ट्रक्चर्स में वैरिएबल देखेंगे या जो भी इस बात का संकेत देंगे कि इनका उपयोग एपीआई के उपभोक्ता द्वारा नहीं किया जाना चाहिए, जैसे कि वे थे निजी।
इस मामले का तथ्य यह है कि इनकैप्सुलेशन कोड को कोड को अधिक बनाए रखने और उपयोग करने में आसान बनाने में मदद कर सकता है। इस वर्ग पर विचार करें:
class VerticalList implements ...
{
private int posX;
private int posY;
... //other members
public void setPosition(int posX, int posY)
{
//change position and move all the objects in the list as well
}
}
यदि इस उदाहरण में चर सार्वजनिक थे, तो इस एपीआई का एक उपभोक्ता भ्रमित होगा कि कब पॉसक्स और पॉसी का उपयोग करना है और कब सेटपोसिशन () का उपयोग करना है। उन विवरणों को छिपाकर आप सहज तरीके से अपने एपीआई का बेहतर उपयोग कर सकते हैं।
सिंटैक्स हालांकि कई भाषाओं में एक सीमा है। हालाँकि नई भाषाएँ ऐसे गुणों की पेशकश करती हैं जो हमें पबिसिस सदस्यों के अच्छे सिंटैक्स और एनकैप्सुलेशन के लाभ प्रदान करती हैं। यदि आप MSVC का उपयोग करते हैं, तो आपको C #, कोटलिन, C ++ में भी गुण मिलेंगे। यहाँ कोटलिन में एक उदाहरण है।
वर्टिकल वर्लिस्ट: ... {var posX: Int सेट (x) {फ़ील्ड = x; ...} var posY: इंट सेट (y) {फ़ील्ड = y; ...}}
यहां हमने जावा उदाहरण में एक ही चीज हासिल की है, लेकिन हम पॉक्सएक्स और पॉसी का उपयोग कर सकते हैं जैसे कि वे सार्वजनिक चर थे। जब मैं हालांकि उनके मूल्य को बदलने की कोशिश करता हूं, तो सेटर सेट () के शरीर को निष्पादित किया जाएगा।
उदाहरण के लिए कोटलिन में, यह जावा बीन के बराबर होगा जिसमें गेटर्स, सेटरर्स, हैशकोड, इक्वल्स और स्टॉल्स लागू होते हैं:
data class DataClass(var data: Int)
ध्यान दें कि यह सिंटैक्स हमें एक पंक्ति में जावा बीन करने की अनुमति कैसे देता है। आपने सही ढंग से इस समस्या पर ध्यान दिया कि जावा जैसी भाषा में एनकैप्सुलेशन को लागू करना है, लेकिन यह जावा की गलती है जो एनकैप्सुलेशन की नहीं है।
आपने कहा था कि आप लोम्बर्स और वासियों को उत्पन्न करने के लिए लोम्बोक के @ डाटा का उपयोग करते हैं। नाम देखिए, @ दाता। यह ज्यादातर डेटा कक्षाओं पर उपयोग किया जाता है जो केवल डेटा को स्टोर करते हैं और इसका मतलब है कि यह क्रमबद्ध और deserialized है। एक गेम से एक सेव फाइल की तरह कुछ सोचें। लेकिन अन्य स्थितियों में, UI तत्व के साथ, आप सबसे निश्चित रूप से बसना चाहते हैं क्योंकि केवल एक चर का मूल्य बदलना अपेक्षित व्यवहार प्राप्त करने के लिए पर्याप्त नहीं हो सकता है।
"It will create getters, setters and setting constructors for all private fields."
- जिस तरह से आप इस उपकरण का वर्णन है, यह लग रहा है जैसे कि यह है कैप्सूलीकरण को बनाए रखने। (कम से कम एक ढीले, स्वचालित, कुछ एनीमिक-मॉडल अर्थ में।) तो वास्तव में समस्या क्या है?