कोड परिसर में Steve McConnell's के समान स्थिति में मैं एक स्थिति में हूं। केवल यही कि मेरी समस्या वाहनों पर आधारित है और ट्राइक उस पर होता है जब कानून कारों की श्रेणी में पड़ता है। कारों के पास अब तक चार पहियों थे। किसी भी तरह से मेरा डोमेन अनावश्यक रूप से जटिल है, इसलिए नीचे बिल्लियों के उदाहरण के साथ रहना आसान है।मैं लिस्कोव प्रतिस्थापन सिद्धांत (एलएसपी) तोड़ने से कैसे बच सकता हूं?
वर्गों है कि एक नियमित ओवरराइड और व्युत्पन्न दिनचर्या यह आमतौर पर आधार वर्ग के डिजाइन में एक त्रुटि दर्शाता है अंदर कुछ नहीं कर से सतर्क रहें। उदाहरण के लिए, मान लीजिए कि आपके पास क्लास कैट और रूटीन स्क्रैच() है और मान लीजिए कि आपको अंततः पता चलता है कि कुछ बिल्लियों को घोषित किया गया है और स्क्रैच नहीं कर सकते हैं। आप स्क्रैचलेस कैट नामक बिल्ली से प्राप्त वर्ग बनाने के लिए लुभाने वाले हो सकते हैं और कुछ भी करने के लिए स्क्रैच() दिनचर्या को ओवरराइड कर सकते हैं। यह दृष्टिकोण कई समस्याओं को प्रस्तुत करता है:
यह अपने इंटरफेस के अर्थशास्त्र को बदलकर बिल्ली कक्षा में प्रस्तुत अमूर्तता (इंटरफ़ेस अनुबंध) का उल्लंघन करता है।
जब आप इसे अन्य व्युत्पन्न कक्षाओं तक बढ़ाते हैं तो यह दृष्टिकोण तुरंत नियंत्रण से बाहर हो जाता है। क्या होता है जब आपको पूंछ के बिना बिल्ली मिलती है? या बिल्ली जो चूहों को पकड़ नहीं पाती है? या एक बिल्ली जो दूध नहीं पीती है? आखिरकार आप व्युत्पन्न कक्षाओं जैसे स्क्रैचलेसटाइलेस मिसलेस मिल्ककेलेस कैट के साथ समाप्त हो जाएंगे।
समय के साथ, यह दृष्टिकोण कोड को जन्म देता है जो को भ्रमित कर रहा है क्योंकि पूर्वजों वर्गों के इंटरफेस और व्यवहार उनके वंशजों के व्यवहार के बारे में बहुत कम या कुछ भी नहीं दर्शाते हैं।
इस समस्या को ठीक करने के लिए स्थान बेस क्लास में नहीं है, लेकिन मूल बिल्ली वर्ग में है। एक पंजे वर्ग बनाएं और बिल्लियों वर्ग के भीतर रखें। मूल समस्या यह धारणा थी कि सभी बिल्लियों खरोंच, इसलिए गंतव्य पर उस समस्या को ठीक करें, बस इसे गंतव्य पर बैंडिंग करने के बजाय।
उपरोक्त अपनी महान पुस्तक के पाठ के मुताबिक। बाद बुरा
जनक क्लास अब वह किसी अन्य वर्ग Claws
बनाने का सुझाव सार
public abstract class Cat {
public void scratch() {
System.out.println("I can scratch");
}
}
व्युत्पन्न वर्ग होने के लिए
public class ScratchlessCat extends Cat {
@Override
public void scratch() {
// do nothing
}
}
नहीं है, लेकिन मैं कैसे समझ में नहीं आता कर सकते हैं मैं ScratchlessCat#Scratch
की आवश्यकता से बचने के लिए इस कक्षा का उपयोग करता हूं।
के रूप में बिल्ली उदाहरण LSP का एक अच्छा उदाहरण है व्यवस्थित करने के लिए एक
DefenseMechanism
वर्ग को परिभाषित कर सकते हैं। एलएसपी के बारे में सीखने में मुझे आश्चर्य हुआ कि एसओ और अन्य साइटों पर कितने खराब उदाहरण हैं और कितनी गलतफहमी है। – SteveT