2009-02-16 9 views
9

Let कहते हैं कि मैं इस तरह एक वर्ग है:Liskov Substition और संरचना

public sealed class Foo 
{ 
    public void Bar 
    { 
     // Do Bar Stuff 
    } 
} 

और मैं यह विस्तार करने के लिए एक विस्तार विधि क्या कर सकते हैं परे कुछ जोड़ना चाहते हैं .... मेरे ही एकमात्र विकल्प रचना है:

public class SuperFoo 
{ 
    private Foo _internalFoo; 

    public SuperFoo() 
    { 
     _internalFoo = new Foo();   
    } 

    public void Bar() 
    { 
     _internalFoo.Bar(); 
    } 

    public void Baz() 
    { 
     // Do Baz Stuff 
    } 
} 

हालांकि यह काम करता है, यह बहुत काम है ... लेकिन मैं अभी भी किसी समस्या का सामना:

public void AcceptsAFoo(Foo a) 

मैं एक फू में पारित कर सकते हैं यहां, लेकिन एक सुपर फू नहीं, क्योंकि सी # को पता नहीं है कि सुपरफू वास्तव में लिस्कोव प्रतिस्थापन भावना में अर्हता प्राप्त करता है ... इसका मतलब है कि संरचना के माध्यम से मेरी विस्तारित कक्षा बहुत सीमित उपयोग है।

इसलिए, यह तय करने के लिए एक ही रास्ता है उम्मीद है कि मूल एपीआई डिजाइनरों एक इंटरफेस के आसपास बिछाने छोड़ दिया है:

public interface IFoo 
{ 
    public Bar(); 
} 

public sealed class Foo : IFoo 
{ 
    // etc 
} 

अब, मैं SuperFoo पर IFoo लागू कर सकते हैं (जो बाद से SuperFoo पहले से ही फू लागू करता है, है सिर्फ हस्ताक्षर बदलने की बात है)।

public class SuperFoo : IFoo 

और आदर्श दुनिया में, तरीकों कि उपभोग फू IFoo के उपभोग होगा:

public void AcceptsAFoo(IFoo a) 

अब, सी # आम इंटरफेस के कारण SuperFoo और फू के बीच के रिश्ते को समझता है और सब कुछ ठीक है।

बड़ी समस्या यह है कि .NET कई कक्षाओं को सील करता है जो कभी-कभी विस्तार करने के लिए अच्छा होता है, और वे आम तौर पर एक सामान्य इंटरफेस को लागू नहीं करते हैं, इसलिए एफओ लेने वाले एपीआई विधियों को सुपरफू स्वीकार नहीं किया जाएगा और आप कर सकते हैं एक अधिभार जोड़ें नहीं।

तो, सभी रचना प्रशंसकों के लिए वहां .... आप इस सीमा के आसपास कैसे जाते हैं?

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

उत्तर

3

मुझे डर है कि छोटा जवाब है, आप जो भी आवश्यक है, बिना कर सकते हैं, यानी इसके बजाए बनाये गये आवृत्ति चर को पास करें।

आप उस प्रकार के निहित या स्पष्ट कलाकार को अनुमति दे सकते हैं (जिसका कार्यान्वयन बस रचित उदाहरण को पारित करता है) लेकिन यह होगा, आईएमओ बहुत बुरा होगा।

छः पत्रिका योग्य उत्तर अच्छा है और मैं इसे फिर से नहीं दबाऊंगा, लेकिन अगर आपने संकेत दिया कि आप कौन सी कक्षाओं की कामना करते हैं तो आप विस्तार कर सकते हैं, हम आपको यह बताने में सक्षम होंगे कि उन्होंने इसे क्यों रोका।

+0

यह सबसे अच्छा जवाब है, हालांकि SixLetterVariable एक उत्कृष्ट बिंदु लाता है। प्रश्न के आगे पढ़ने पर – FlySwat

+0

+1, आपने वास्तव में इसका उत्तर दिया। उसे एहसास नहीं हुआ कि वह पहले तकनीकी कार्यवाही की तलाश में था! – user7116

14

मैंने खुद को वही प्रश्न पूछने तक पाया जब तक कि मैंने अपने स्वयं के पुन: प्रयोज्य पुस्तकालयों पर काम करना शुरू नहीं किया। कई बार आप कुछ वर्गों के साथ उड़ते हैं जिन्हें कार्यान्वयनकर्ता से कॉल के अस्पष्ट या आर्केन अनुक्रमों की आवश्यकता के बिना विस्तारित नहीं किया जा सकता है।

अपनी कक्षा को विस्तारित करने की अनुमति देते समय, आपको यह पूछना होगा: यदि कोई डेवलपर मेरी कक्षा को बढ़ाता है, और इस नई कक्षा को मेरी लाइब्रेरी में पास करता है, तो क्या मैं पारदर्शी रूप से इस नई कक्षा के साथ काम कर सकता हूं? क्या मैं इस नई कक्षा के साथ ठीक से काम कर सकता हूं? क्या यह नई कक्षा वास्तव में वही व्यवहार करने जा रही है?

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

यह आपके प्रश्न का बिल्कुल जवाब नहीं देता है, लेकिन यह अंतर्दृष्टि प्रदान करता है कि सभी वर्ग नेट फ्रेमवर्क में विरासत में क्यों नहीं हैं (और आपको शायद अपने कुछ वर्गों को सील करने का मनोरंजन क्यों करना चाहिए)।

+1

++ एक फ्रेमवर्क वर्ग को सही ढंग से डिजाइन करने के लिए सही ढंग से डिजाइन करना * हार्ड * है। यदि ओपी ने संकेत दिया कि वह कौन से वर्ग चाहता है तो वह इसे संभव बना सकता है कि इसे या तो – ShuggyCoUk

+1

++ समझाया जा सकता है यदि आप दूसरों द्वारा विस्तार के लिए खोलते हैं तो आप भविष्य के एक्सटेंशन की संख्या को भी सीमित कर सकते हैं जो आप स्वयं कर सकते हैं। – krosenvold

संबंधित मुद्दे