इसका क्या मतलब है जब कोई कहता है कि "अलग-अलग क्या होता है"?


25

OOP सिद्धांतों में से एक मैं भर में आया है: -Encapsulate क्या बदलता है।

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


En.wikipedia.org/wiki/Encapsulation_(computer_programming) देखें जो इसे अच्छे से समझाता है। मुझे लगता है कि "क्या भिन्न होता है" सही नहीं है क्योंकि आपको कभी-कभी स्थिरांक को भी बदलना चाहिए।
qwerty_so 8

I don't know how exactly would it contribute to a better design"मॉडल" और कार्यान्वयन विवरण के बीच ढीले युग्मन के बारे में विवरण संलग्न है। कम बद्ध कार्यान्वयन विवरण के लिए "मॉडल" है, अधिक लचीला समाधान है। और इसे विकसित करना आसान बनाता है। "अपने आप को विवरण से सार करें"।
लैव

@ लिव सो "भिन्न" से तात्पर्य है कि आपके सॉफ़्टवेयर जीवन चक्र के दौरान क्या विकसित होता है या आपके कार्यक्रम के निष्पादन के दौरान क्या परिवर्तन होता है या दोनों?
हरिस गौरी

2
@ हरिसगौरी दोनों। एक साथ समूह जो एक साथ बदलता है। स्वतंत्र रूप से अलग-अलग होता है। इस बात पर संदेह करें कि आप क्या मानेंगे कभी नहीं बदलेंगे।
कैंडिड_ऑरेंज 22

1
@ जीव सोच "अमूर्त" एक अच्छा बिंदु है। ऐसा करना भारी पड़ सकता है। किसी एक वस्तु में आपको एक ज़िम्मेदारी दी गई है। इसके बारे में अच्छी बात यह है कि आपको केवल उस एक चीज के बारे में ध्यान से सोचना होगा। जब बाकी की समस्या का विवरण किसी को होता है तो यह समस्या आसान हो जाती है।
कैंडिड_ओरेंज

जवाबों:


30

आप ऐसा कोड लिख सकते हैं जो ऐसा दिखता है:

if (pet.type() == dog) {
  pet.bark();
} else if (pet.type() == cat) {
  pet.meow();
} else if (pet.type() == duck) {
  pet.quack()
}

या आप ऐसा कोड लिख सकते हैं जो ऐसा दिखता है:

pet.speak();

यदि भिन्न होता है, तो आप इसके बारे में चिंता करने की जरूरत नहीं है। आप बस इस बात की चिंता करते हैं कि आपको क्या चाहिए और आप जो भी आंकड़े इस्तेमाल कर रहे हैं वह कैसे करना है जो आपको वास्तव में क्या विविधताओं के आधार पर चाहिए।

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

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

आप इस उदाहरण को देख सकते हैं और सोच सकते हैं कि मैं बहुरूपता और अतिक्रमण को स्वीकार कर रहा हूं। मैं नहीं। मैं "क्या भिन्न होता है" और "विवरण" का अनुमान लगा रहा हूं।

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

बाकी कोड से विवरणों को अलग, अलग और छिपाएं। अपने सिस्टम के माध्यम से विवरणों का ज्ञान न होने दें और आप "ठीक है क्या बदलता है" का अनुसरण कर रहे हैं।


3
यह वास्तव में अजीब है। "मेरे लिए क्या बदलता है" का अर्थ है राज्य परिवर्तनों को दूर करने का मतलब है, जैसे कि वैश्विक चर कभी नहीं होते हैं। लेकिन आप जवाब भी समझ में आता है, भले ही यह सांकेतिक शब्दों की तुलना में बहुरूपता के लिए एक जवाब अधिक लगता है :)
डेविड Arno

2
@DavidArno बहुरूपता इस काम को बनाने का एक तरीका है। मैं सिर्फ अगर पालतू जानवर में संरचना तैयार कर सकता था और चीजें पालतू के इनकैप्सुलेशन की बदौलत यहां अच्छी लगेंगी। लेकिन यह सिर्फ गंदगी को साफ करने के बजाय चारों ओर घूम रहा होगा।
candied_orange 7

1
"जो कुछ भी बदलता है उसे एनकैप्सुलेट करें" का अर्थ है कि राज्य के परिवर्तनों को छिपाना । नाय, नाय। मुझे सीओ की टिप्पणी पसंद है। डेरिक एल्किन का जवाब गहरा हो जाता है, इसे एक से अधिक बार पढ़ें। जैसा कि @JacquesB ने कहा "यह सिद्धांत वास्तव में काफी गहरा है"
radarbob

16

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

मान लें कि आपके पास एक एप्लिकेशन है जो बहुत सारे स्थानों पर बिक्री कर गणना का उपयोग करता है। यदि बिक्री कर दर में परिवर्तन होता है, तो आप क्या पसंद करेंगे:

  • बिक्री कर की गणना उस एप्लिकेशन में हर जगह एक हार्डकोडेड शाब्दिक है जहां बिक्री कर की गणना की जाती है।

  • बिक्री कर की दर एक वैश्विक स्थिरांक है, जिसका उपयोग हर उस स्थान पर किया जाता है जहां बिक्री कर की गणना की जाती है।

  • एक एकल विधि है जिसे calculateSalesTax(product)बिक्री कर की दर का उपयोग करने के लिए एकमात्र स्थान कहा जाता है।

  • बिक्री कर की दर एक कॉन्फ़िगरेशन फ़ाइल या डेटाबेस फ़ील्ड में निर्दिष्ट है।

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

अब एक और स्थिरांक पर विचार करें, पाई, जिसका उपयोग कोड में बहुत सी जगहों पर भी किया जाता है। क्या एक ही डिजाइन सिद्धांत धारण करता है? नहीं, क्योंकि पाई बदलने वाली नहीं है। कॉन्फ़िगरेशन फ़ाइल या डेटाबेस फ़ील्ड में इसे निकालने से केवल अनावश्यक जटिलता का परिचय होता है (और बाकी सब समान होने पर, हम सबसे सरल कोड पसंद करते हैं)। विसंगतियों से बचने और पठनीयता में सुधार करने के लिए इसे कई स्थानों पर हार्डकोड के बजाय इसे वैश्विक स्थिर बनाने के लिए समझ में आता है।

मुद्दा यह है, अगर हम केवल यह देखते हैं कि कार्यक्रम अब कैसे काम करता है , बिक्री कर दर और पाई बराबर है, दोनों स्थिर हैं। केवल जब हम विचार करते हैं कि भविष्य में क्या भिन्न हो सकता है , क्या हमें एहसास होता है कि हमें उन्हें डिजाइन में अलग तरह से व्यवहार करना होगा।

यह सिद्धांत वास्तव में काफी गहरा है, क्योंकि इसका मतलब है कि आपको सिर्फ यह देखना होगा कि आज कोड आधार क्या करना है , और बाहरी ताकतों पर भी विचार करें, जो इसे बदलने का कारण बन सकती हैं, और यहां तक ​​कि आवश्यकताओं के पीछे विभिन्न हितधारकों को भी समझ सकती हैं।


2
कर एक अच्छा उदाहरण हैं। कानून और कर बछड़े एक दिन से दूसरे दिन बदल सकते हैं। यदि आप एक कर घोषणा प्रणाली को लागू कर रहे हैं तो आप इस प्रकार के परिवर्तनों से दृढ़ता से बंधे हैं। एक लोकेल से दूसरे (देशों, प्रांतों, ...) में भी परिवर्तन होता है
Laiv

"पाई बदलने वाली नहीं है" ने मुझे हंसाया। यह सच है, पाई बदलने की संभावना नहीं है, लेकिन मान लीजिए कि आपको इसका उपयोग करने की अनुमति नहीं थी? यदि कुछ लोगों के पास पाई है तो उन्हें पदावनत कर दिया जाएगा। मान लीजिए कि एक आवश्यकता बन जाती है? आशा है कि आपको एक ताऊ दिवस मुबारक हो । अच्छा जवाब BTW। दीप वास्तव में।
कैंडिड_ऑरेंज

14

दोनों वर्तमान उत्तर केवल आंशिक रूप से निशान को हिट करने के लिए प्रतीत होते हैं, और वे उन उदाहरणों पर ध्यान केंद्रित करते हैं जो मुख्य विचार को बादलते हैं। यह भी (पूरी तरह से) एक ओओपी सिद्धांत नहीं है, लेकिन सामान्य रूप से एक सॉफ्टवेयर डिजाइन सिद्धांत है।

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

यह केवल अप्रत्यक्ष रूप से एनकैप्सुलेटिंग स्टेट से संबंधित है, जो मुझे लगता है कि डेविड अर्नो के बारे में सोच रहा है। यह सलाह हमेशा (लेकिन अक्सर नहीं) राज्य को घेरने का सुझाव देती है, और यह सलाह अपरिवर्तनीय वस्तुओं पर भी लागू होती है। वास्तव में, केवल नामांकित स्थिरांक एक (बहुत बुनियादी) रूप है जो अलग-अलग होता है।

CandiedOrange स्पष्ट रूप से "क्या" के साथ "विवरण" बदलता है। यह केवल आंशिक रूप से सही है। मैं मानता हूं कि जो भी कोड होता है, वह कुछ अर्थों में "विवरण" होता है, लेकिन एक "विवरण" भिन्न नहीं हो सकता (जब तक कि आप इस विवरण को बनाने के लिए "विवरण" को परिभाषित नहीं करते)। गैर-अलग-अलग विवरणों को संलग्न करने के कारण हो सकते हैं, लेकिन यह तानाशाही एक नहीं है। मोटे तौर पर, यदि आप अत्यधिक आश्वस्त थे कि "डॉग", "कैट", और "डक" एकमात्र प्रकार होंगे जिनसे आपको कभी भी निपटना होगा, तो यह डिक्टम रिफ्लेक्टिंग कैंडिडऑरेंज का सुझाव नहीं देता है।

एक अन्य संदर्भ में CandiedOrange का उदाहरण कास्टिंग करें, मान लें कि हमारे पास सी जैसी प्रक्रियात्मक भाषा है। यदि मेरे पास कुछ कोड हैं:

if (pet.type() == dog) {
  pet.bark();
} else if (pet.type() == cat) {
  pet.meow();
} else if (pet.type() == duck) {
  pet.quack()
}

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

void speak(pet) {
  if (pet.type() == dog) {
    pet.bark();
  } else if (pet.type() == cat) {
    pet.meow();
  } else if (pet.type() == duck) {
    pet.quack()
  }
}

और कोड के ब्लॉक के बजाय इस नई प्रक्रिया का उपयोग करना (यानी "एक्स्ट्रेक्ट मेथड" रिफैक्टिंग)। इस बिंदु पर एक "गाय" प्रकार या जो भी केवल speakप्रक्रिया को अद्यतन करने की आवश्यकता है । बेशक, एक OO भाषा में आप इसके बजाय कैंडिडऑरेन्ज के उत्तर के रूप में गतिशील प्रेषण का लाभ उठा सकते हैं। यह स्वाभाविक रूप से होगा यदि आप petएक इंटरफ़ेस के माध्यम से एक्सेस करते हैं । गतिशील प्रेषण के माध्यम से सशर्त तर्क को खत्म करना एक ऑर्थोगोनल चिंता है जो इस बात का हिस्सा था कि मैंने इस प्रक्रियात्मक प्रतिपादन को क्यों बनाया। मैं इस बात पर भी जोर देना चाहता हूं कि इसमें ओओपी के लिए विशेष रूप से सुविधाओं की आवश्यकता नहीं है। यहां तक ​​कि एक OO भाषा में, जो अलग-अलग होता है, उसका मतलब यह नहीं होता है कि नए वर्ग या इंटरफ़ेस को बनाने की आवश्यकता है।

अधिक कट्टरपंथी उदाहरण के रूप में (जो कि काफी ओओ के करीब है), कहते हैं कि हम एक सूची से डुप्लिकेट को निकालना चाहते हैं। मान लें कि हमने सूची में अब तक देखी गई वस्तुओं पर नज़र रखते हुए इसे लागू कर दिया है और जो सूची में हमने देखा है उसे हटा दिया है। यह मानना ​​उचित है कि हम चाहते हैं कि हम कम से कम, प्रदर्शन कारणों से देखी गई वस्तुओं पर नज़र कैसे रखें। जो भिन्न होता है, उसे एनकैप्सुलेट करने का ताना-बाना बताता है कि हमें देखा वस्तुओं के सेट का प्रतिनिधित्व करने के लिए एक अमूर्त डेटा प्रकार का निर्माण करना चाहिए। हमारा एल्गोरिथ्म अब इस अमूर्त सेट डेटा प्रकार के खिलाफ परिभाषित किया गया है, और अगर हम एक द्विआधारी खोज ट्री पर स्विच करने का निर्णय लेते हैं, तो हमारे एल्गोरिथ्म को बदलने या देखभाल करने की आवश्यकता नहीं है। OO भाषा में, हम इस अमूर्त डेटा प्रकार को पकड़ने के लिए एक वर्ग या इंटरफ़ेस का उपयोग कर सकते हैं। SML / O 'जैसी भाषा में

आवश्यकताओं से प्रेरित उदाहरण के लिए, मान लें कि आपको कुछ व्यावसायिक तर्क के संबंध में कुछ क्षेत्र को मान्य करने की आवश्यकता है। जबकि आपके पास अब विशिष्ट आवश्यकताएं हो सकती हैं, आपको दृढ़ता से संदेह है कि वे विकसित होंगे। आप वर्तमान तर्क को इसकी प्रक्रिया / कार्य / नियम / वर्ग में शामिल कर सकते हैं।

हालांकि यह एक ऑर्थोगोनल चिंता है जो "अलग-अलग क्या होता है" का हिस्सा नहीं है, यह अक्सर अमूर्त करने के लिए स्वाभाविक है, जो कि, अब एनकैप्सुलेटेड लॉजिक द्वारा संचालित होता है। यह आम तौर पर अधिक लचीले कोड की ओर जाता है और अतिक्रमित लॉजिक को संशोधित करने के बजाय वैकल्पिक कार्यान्वयन में प्रतिस्थापित करके तर्क को बदलने की अनुमति देता है।


ओह कड़वी मीठी विडंबना। हां, यह पूरी तरह से एक OOP मुद्दा नहीं है। आपने मुझे एक भाषा के प्रतिमान का विवरण देते हुए पकड़ा और मेरे उत्तर को उचित रूप से "भिन्न" करके मुझे इसके लिए दंडित किया।
कैंडिड_ऑरेंज

"यहां तक ​​कि एक ओओ भाषा में, जो अलग-अलग होता है उसका मतलब यह नहीं है कि एक नया वर्ग या इंटरफ़ेस बनाने की आवश्यकता है" - यह एक ऐसी स्थिति की कल्पना करना मुश्किल है जहां एक नया वर्ग या इंटरफ़ेस नहीं बना रहा है एसआरपी का उल्लंघन नहीं होगा
taurelas

11

"जो अलग-अलग होता है उसे लागू करें" कार्यान्वयन विवरणों को छिपाने के लिए संदर्भित करता है जो बदल सकता है और विकसित हो सकता है।

उदाहरण:

उदाहरण के लिए, मान लीजिए कि वर्ग Courseट्रैक रख Studentsसकता है ()। आप इसे लागू कर सकते हैं LinkedListऔर उस पर पुनरावृत्ति की अनुमति देने के लिए कंटेनर को उजागर कर सकते हैं:

class Course { 
    public LinkedList<Student> Atendees; 
    public bool register (Student s);  
    ...
}

लेकिन यह एक अच्छा विचार नहीं है:

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

यदि आप अलग-अलग होते हैं (या कहा गया है, क्या भिन्न हो सकता है), तो आप दोनों का उपयोग कर कोड और इनकैप्सुलेटेड क्लास दोनों को एक-दूसरे को विकसित करने के लिए स्वतंत्रता रखते हैं। यही कारण है कि यह OOP में एक महत्वपूर्ण सिद्धांत है।

अतिरिक्त पढ़ने:

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