दिलचस्प पोस्ट
किसी भी तरह से एक WPF पाठब्लॉक चयन करने योग्य है? URL मैच करने के लिए रेगेक्स घातक त्रुटि: ऑब्जेक्ट संदर्भ में नहीं होने पर $ का उपयोग करना IIS7 – (413) अनुरोध इकाई बहुत बड़ा है | uploadReadAheadSize क्रैश या "विभाजन गलती" जब डेटा की प्रतिलिपि बनाई गई है / स्कैन / अपर्याप्त संकेतक को पढ़ना कैसे PHP में एक रीडायरेक्ट बनाने के लिए? यूआरएल को कैसे पार्स करना है? जावा में क्या <> (कोण कोष्ठक) का मतलब है? इंटरफ़ेस चर का उपयोग करना मैं किसी को जीआईटी रिपॉजिटरी कैसे ईमेल कर सकता हूं? HTML5: "रेडियो" इनपुट फ़ील्ड के साथ "अपेक्षित" विशेषता का उपयोग कैसे करें JQuery के साथ एक सरणी कैसे प्राप्त करें, एक ही नाम के साथ एकाधिक <input> कस्टम शैलियों के साथ मैं डिफ़ॉल्ट PrimeFaces सीएसएस को ओवरराइड कैसे कर सकता हूं? OpenCV में आरजीबी को ब्लैक एंड व्हाइट में कनवर्ट करें आर में मिश्रित संख्याओं और अक्षरों के तारों का संख्यात्मक हिस्सा निकालें

क्या आयताकार से स्क्वायर को लेकर लिस्कॉव के प्रतिस्थापन सिद्धांत का उल्लंघन हो रहा है?

मैं डिजाइन सिद्धांतों को डिजाइन और सीखने के लिए नया हूँ।

यह कहते हैं कि आयताकार से स्क्वायर प्राप्त करना लिस्कॉव के प्रतिस्थापन सिद्धांत के उल्लंघन का एक उत्कृष्ट उदाहरण है।

अगर ऐसा मामला है, तो सही डिजाइन क्या होना चाहिए?

वेब के समाधान से एकत्रित समाधान "क्या आयताकार से स्क्वायर को लेकर लिस्कॉव के प्रतिस्थापन सिद्धांत का उल्लंघन हो रहा है?"

मेरा मानना ​​है कि तर्क कुछ ऐसा है:

मान लें कि आपके पास एक ऐसा तरीका है जो आयताकार स्वीकार करता है और इसकी चौड़ाई समायोजित करता है:

public void SetWidth(Rectangle rect, int width) { rect.Width = width; } 

यह पूरी तरह से उचित होना चाहिए, यह देखते हुए कि यह आयत क्या है, यह परीक्षण पारित होगा:

 Rectangle rect = new Rectangle(50, 20); // width, height SetWidth(rect, 100); Assert.AreEqual(20, rect.Height); 

… क्योंकि आयताकार की चौड़ाई बदलने से उसकी ऊंचाई प्रभावित नहीं होती है

हालांकि, मान लें कि आपने आयत से एक नया वर्ग वर्ग प्राप्त किया है। परिभाषा के अनुसार, एक वर्ग की ऊंचाई और चौड़ाई हमेशा समान होती है। चलिए उस परीक्षा को फिर से आज़माएं:

 Rectangle rect = new Square(20); // both width and height SetWidth(rect, 100); Assert.AreEqual(20, rect.Height); 

यह परीक्षण असफल हो जायेगा, क्योंकि एक चौड़ाई की चौड़ाई 100 तक निर्धारित करने से इसकी ऊंचाई भी बदल जाएगी।

इस प्रकार, लिस्कोव के प्रतिस्थापन सिद्धांत को स्क्वायर से आयताकार बनाकर उल्लंघन किया जाता है।

"एक-एक" नियम "वास्तविक दुनिया" (एक वर्ग निश्चित रूप से एक आयताकार प्रकार) में समझ में आता है, लेकिन हमेशा सॉफ्टवेयर डिजाइन की दुनिया में नहीं है।

संपादित करें

आपके प्रश्न का उत्तर देने के लिए, सही डिजाइन होना चाहिए कि दोनों आयत और स्क्वायर एक आम "बहुभुज" या "आकार" वर्ग से प्राप्त होते हैं, जो चौड़ाई या ऊंचाई के संबंध में किसी भी नियम को लागू नहीं करता है

उत्तर परिवर्तनशीलता पर निर्भर करता है। अगर आपका आयत और वर्ग वर्ग अपरिवर्तनीय हैं, तो Square वास्तव में Rectangle का एक उपप्रकार है और दूसरा से पहले प्राप्त करने के लिए बिल्कुल ठीक है। अन्यथा, Rectangle और Square बिना किसी IRectangle पर्दाफाश कर सकते थे, लेकिन एक दूसरे से गलत लेना गलत है क्योंकि न तो टाइप ठीक से दूसरे का एक उपप्रकार है

मैं सहमत नहीं हूं कि आयताकार वर्ग से प्राप्त वर्ग अनिवार्य रूप से एलएसपी का उल्लंघन करता है।

मैट के उदाहरण में, अगर आपके पास कोड है जो चौड़ाई और ऊंचाई पर निर्भर है, तो यह वास्तव में एलएसपी का उल्लंघन करता है।

यदि हालांकि, आप किसी भी मान्यताओं को तोड़ने के बिना अपने कोड में हर जगह एक वर्ग के लिए एक आयताकार स्थानापन्न कर सकते हैं, तो आप एलएसपी का उल्लंघन नहीं कर रहे हैं।

तो यह वास्तव में नीचे आता है कि आपके समाधान में अमूर्त आयत का क्या मतलब है।

मैं हाल ही में इस समस्या के साथ संघर्ष कर रहा था और मुझे लगा कि मैं अपनी टोपी को अंगूठी में जोड़ूंगा:

 public class Rectangle { protected int height; protected int width; public Rectangle (int height, int width) { this.height = height; this.width = width; } public int computeArea () { return this.height * this.width; } public int getHeight () { return this.height; } public int getWidth () { return this.width; } } public class Square extends Rectangle { public Square (int sideLength) { super(sideLength, sideLength); } } public class ResizableRectangle extends Rectangle { public ResizableRectangle (int height, int width) { super(height, width); } public void setHeight (int height) { this.height = height; } public void setWidth (int width) { this.width = width; } } 

पिछले वर्ग, ResizableRectangle नोटिस "Resizableness" को एक उपवर्ग में स्थानांतरित करके, हमें वास्तव में हमारे मॉडल को सुधारने के दौरान कोड पुनः उपयोग मिलता है इसके बारे में सोचें: एक स्क्वायर शेष होने पर एक स्क्वायर को आज़ादी से नहीं बदला जा सकता है, जबकि गैर-स्क्वायर आयतें कर सकती हैं। हालांकि, सभी आयत को फिर से बदल नहीं सकते हैं, क्योंकि एक वर्ग एक आयताकार है (और इसकी "पहचान" को बनाए रखने के समय इसे स्वतंत्र रूप से नहीं बदला जा सकता है)। (ओ_ ओ) तो यह एक आधार Rectangle वर्ग बनाने के लिए समझ में आता है जो कि पुन: आकारणीय नहीं है, क्योंकि यह कुछ आयताकारों की एक अतिरिक्त संपत्ति है।

मान लीजिए कि हमारे पास वर्ग आयत को दो के साथ (सादगी के लिए सार्वजनिक) संपत्ति की चौड़ाई, ऊंचाई हम उन दो गुणों को बदल सकते हैं: r.width = 1, r.height = 2
अब हम कहते हैं कि एक स्क्वायर is_a आयताकार है। लेकिन हालांकि दावा है "एक वर्ग एक आयत की तरह व्यवहार करेगा" हम सेट नहीं कर सकते। Width = 1 और .high = 2 एक वर्ग ऑब्जेक्ट पर (यदि आप ऊंचाई निर्धारित करते हैं और इसके विपरीत, आपका वर्ग शायद चौड़ाई समायोजित करता है)। इसलिए कम से कम एक ऐसा मामला है जहां प्रकार का एक वर्ग स्क्वायर आयत की तरह व्यवहार नहीं करता है और इसलिए आप उन्हें पूरी तरह से नहीं बदल सकते।

मुझे विश्वास है कि वास्तविक दुनिया का प्रतिनिधित्व करने के लिए सॉफ्टवेयर को सक्षम करने के लिए OOD / OOP तकनीक मौजूद हैं। वास्तविक दुनिया में एक वर्ग एक आयताकार होता है जिसमें समान पक्ष होते हैं वर्ग केवल एक वर्ग है क्योंकि इसका समान पक्ष है, इसलिए नहीं कि उसने एक वर्ग बनने का फैसला किया है। इसलिए, ओ ओ कार्यक्रम को इसके साथ निपटने की जरूरत है। बेशक, यदि ऑब्जेक्ट को चालू करने वाला रूटीन चौराहे चाहता है, तो यह लंबाई की संपत्ति और चौड़ाई वाली संपत्ति को समान राशि के बराबर निर्दिष्ट कर सकता है। यदि वस्तु का उपयोग करने वाले प्रोग्राम को बाद में पता होना चाहिए कि यह स्क्वायर है, तो उसे केवल पूछने की आवश्यकता है। ऑब्जेक्ट में केवल पढ़ने के लिए बूलियन संपत्ति "स्क्वायर" नामक हो सकती है जब कॉलिंग दिनचर्या इसे आमंत्रित करती है, तो ऑब्जेक्ट (लंबाई = चौड़ाई) वापस कर सकती है। अब यह मामला हो सकता है भले ही आयत वस्तु अपरिवर्तनीय हो। इसके अलावा, अगर आयत वास्तव में अपरिवर्तनीय है, तो स्क्वायर संपत्ति का मूल्य कन्स्ट्रक्टर में सेट किया जा सकता है और इसके साथ किया जा सकता है। तो यह एक मुद्दा क्यों है? एलएसपी को उप-वस्तुओं को लागू करने के लिए अपरिवर्तनीय होने की आवश्यकता होती है और एक आयत के उप-ऑब्जेक्ट के रूप में स्क्वायर को अक्सर इसके उल्लंघन के उदाहरण के रूप में उपयोग किया जाता है लेकिन यह अच्छा डिजाइन नहीं प्रतीत होता है क्योंकि जब उपयोग की जाने वाली रूटीन वस्तु को "ओब्ज़स्क्वेयर" के रूप में कहती है, तो इसकी आंतरिक विस्तार जानना चाहिए। क्या यह बेहतर नहीं होगा अगर यह परवाह नहीं है कि आयताकार वर्ग था या नहीं? और ऐसा इसलिए होगा क्योंकि आयताकार के तरीकों की परवाह किए बिना सही होगा। क्या एलएसपी का उल्लंघन करने का एक बेहतर उदाहरण है?

एक और सवाल: एक वस्तु कैसे अपरिवर्तनीय बना है? क्या एक "अपरिवर्तनीय" संपत्ति है जिसे तत्काल पर सेट किया जा सकता है?

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

समस्या यह है कि जो वर्णित किया जा रहा है वह वास्तव में "प्रकार" नहीं है, लेकिन एक संचयी आकस्मिक संपत्ति है।

आपके पास वास्तव में एक चतुर्भुज है और यह कि दोनों "स्क्वेयरनेस" और "आयताकार" केवल कोणों और पक्षों के गुणों से प्राप्त आकस्मिक कलाकृतियों हैं।

"स्क्वायर" (या फिर आयताकार) की पूरी अवधारणा सिर्फ एक दूसरे के संबंध में वस्तु की संपत्तियों के संग्रह का एक सार प्रतिनिधित्व है और प्रश्न में वस्तु है, न कि वस्तु का प्रकार और इसके आत्म में।

यह वह जगह है जहां एक विशिष्ट भाषा के संदर्भ में समस्या की सोच में मदद मिल सकती है, क्योंकि यह ऐसा प्रकार नहीं है जो यह निर्धारित करता है कि यह "एक वर्ग" है, लेकिन वस्तु का वास्तविक गुण है जो निर्धारित करता है कि क्या यह "एक वर्ग" है।

मुझे लगता है कि यदि आप अमूर्त को आगे भी लेना चाहते हैं तो आप यह भी नहीं कहेंगे कि आपके पास चतुर्भुज है लेकिन आपके पास बहुभुज या सिर्फ एक आकार भी है

इसकी बहुत सरल 🙂 अधिक 'आधार' वर्ग (व्युत्पन्न श्रृंखला में पहला) सबसे सामान्य होना चाहिए।

उदाहरण के आकार के लिए -> आयत -> स्क्वायर

यहां एक वर्ग एक आयताकार (विवश आयामों के साथ) का एक विशेष मामला है और एक आयत आकार का एक विशेष प्रकार है।

एक अन्य तरीके से कहा – "एक है" परीक्षा का उपयोग करें एक स्क्वायर एक आयत है लेकिन एक आयत हमेशा एक वर्ग नहीं है।