वंशानुक्रम पदानुक्रम में लिस्कोव प्रतिस्थापन सिद्धांत को कैसे सत्यापित किया जाए?


14

इस उत्तर से प्रेरित :

Liskov प्रतिस्थापन सिद्धांत की आवश्यकता है कि

  • उपसर्गों को एक उपप्रकार में मजबूत नहीं किया जा सकता है।
  • उपसंहार को उपप्रकार में कमजोर नहीं किया जा सकता है।
  • सुपरपाइप के हमलावर को एक उपप्रकार में संरक्षित किया जाना चाहिए।
  • इतिहास की बाधा ("इतिहास का नियम")। वस्तुओं को केवल उनके तरीकों (इनकैप्सुलेशन) के माध्यम से परिवर्तनीय माना जाता है। चूंकि उपप्रकार उन विधियों को प्रस्तुत कर सकता है जो सुपरटाइप में मौजूद नहीं हैं, इसलिए इन विधियों का परिचय उपप्रकार में राज्य परिवर्तन की अनुमति दे सकता है जो सुपरटाइप में अनुमेय नहीं हैं। इतिहास की बाधा इस पर रोक लगाती है।

मैं उम्मीद कर रहा था कि अगर कोई वर्ग पदानुक्रम पोस्ट करेगा जो इन 4 बिंदुओं का उल्लंघन करता है और तदनुसार उन्हें कैसे हल किया जाए।
मैं शैक्षिक उद्देश्यों के लिए एक विस्तृत विवरण की तलाश कर रहा हूं कि पदानुक्रम में 4 बिंदुओं में से प्रत्येक को कैसे पहचाना जाए और इसे ठीक करने का सबसे अच्छा तरीका है।

नोट:
मैं काम करने के लिए लोगों के लिए एक कोड नमूना पोस्ट करने की उम्मीद कर रहा था, लेकिन सवाल ही यह है कि दोषपूर्ण हंटर किंगडम की पहचान कैसे करें :)


जवाबों:


17

यह उस बोली की तुलना में बहुत अधिक सरल है जो इसे सटीक बनाता है।

जब आप एक विरासत पदानुक्रम को देखते हैं, तो एक विधि की कल्पना करें जो बेस क्लास का एक ऑब्जेक्ट प्राप्त करता है। अब अपने आप से पूछें, क्या ऐसी कोई धारणा है कि इस पद्धति को संपादित करने वाला कोई व्यक्ति उस वर्ग के लिए अमान्य हो सकता है।

उदाहरण के लिए ( मूल रूप से अंकल बॉब की साइट पर देखा गया ):

public class Square : Rectangle
{
    public Square(double width) : base(width, width)
    {
    }

    public override double Width
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Width;
        }
    }

    public override double Height
    {
        set
        {
            base.Width = value;
            base.Height = value;
        }
        get
        {
            return base.Height;
        }
    }
}

काफी उचित लगता है, है ना? मैंने एक विशेष प्रकार का आयत बनाया है जिसे स्क्वायर कहा जाता है, जो बताता है कि चौड़ाई हर समय ऊँचाई के बराबर होनी चाहिए। एक वर्ग एक आयत है, इसलिए यह OO सिद्धांतों के साथ फिट बैठता है, है ना?

लेकिन रुकिए, अगर कोई इस विधि को लिखता है तो क्या होगा:

public void Enlarge(Rectangle rect, double factor)
{
    rect.Width *= factor;
    rect.Height *= factor;
}

अछा नहीं लगता। लेकिन कोई कारण नहीं है कि इस पद्धति के लेखक को पता होना चाहिए कि एक संभावित समस्या हो सकती है।

हर बार जब आप एक वर्ग को दूसरे से प्राप्त करते हैं, तो आधार वर्ग के बारे में सोचें और लोग इसके बारे में क्या मान सकते हैं (जैसे कि "इसकी एक चौड़ाई और ऊँचाई है और वे दोनों स्वतंत्र होंगे")। फिर सोचें "क्या वे धारणाएँ मेरे उपवर्ग में मान्य हैं?" यदि नहीं, तो अपने डिज़ाइन पर पुनर्विचार करें।


बहुत अच्छा और सूक्ष्म उदाहरण। +1। आप क्या कर सकते हैं, एनर्जेज को आयत वर्ग की एक विधि बना सकते हैं और इसे स्क्वायर वर्ग में ओवरराइड कर सकते हैं।
मार्को-फिसेट

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

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

@pdr उदाहरण के लिए धन्यवाद, लेकिन मैंने अपनी पोस्ट में जिन 4 शर्तों का उल्लेख किया है, उनके विषय में Squareकक्षा का कौन सा हिस्सा उनका उल्लंघन करता है?
सांगो

1
@Songo: यह इतिहास की बाधा है। यहां बेहतर समझाया गया: blackwasp.co.uk/LSP.aspx "उनके स्वभाव से, उपवर्गों में उनके सुपरक्लास के सभी तरीके और गुण शामिल हैं। वे आगे के सदस्यों को भी जोड़ सकते हैं। इतिहास की बाधा कहती है कि नए या संशोधित सदस्यों को संशोधित नहीं करना चाहिए। एक वस्तु की स्थिति इस तरह से है जिसे आधार वर्ग द्वारा अनुमति नहीं दी जाएगी । उदाहरण के लिए, यदि आधार वर्ग एक निश्चित आकार के साथ किसी वस्तु का प्रतिनिधित्व करता है, तो उपवर्ग को इस आकार को संशोधित करने की अनुमति नहीं देनी चाहिए। "
पीडीआर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.