2013-02-03 34 views
6

तोड़ने एक परियोजना मैं हाल ही में काम में नुकसान, देखा कि कुछ तरीकों कि एक वर्ग है कि एक पदानुक्रम के अंतर्गत आता है स्वीकार कर रहे थे, निम्न के समान कोड था:कक्षा उपयोग Liskov प्रतिस्थापन सिद्धांत

public void Process(Animal animal) { 
    if(animal.GetType() == typeof(Dog)) { 
     Console.WriteLine("We have a dog"); 
    } 
    else { 
     Console.WriteLine("not a dog"); 
    } 
} 

ठीक है, कि एलएसपी के एक स्पष्ट उल्लंघन के रूप में मुझे मारा, क्योंकि अब यदि आप कुत्ते के उप-वर्ग का उपयोग करते हैं, या तो उत्पादन कोड, इकाई परीक्षण नकली, या निर्भरता इंजेक्शन इंटरसेप्टर के हिस्से के रूप में यह कोड उसी तरह काम नहीं करेगा। मेरा मानना ​​है कि इस विशेष परिदृश्य आसानी से ठीक किया जा सकता, करने के लिए हालत को बदलने के द्वारा:

if (animal is Dog) 

जो मुझे हालांकि सोच गया:

क्या कोई अन्य नुकसान है कि ग्राहक कोड में LSP तोड़ सकते हैं देखने के लिए कर रहे हैं?

अद्यतन

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

उत्तर और लिंक के माध्यम से जाने के बाद भी मैं देख सकता हूं कि केवल एक ही पिटफॉल सीधे कक्षा के प्रकार का उपयोग करना होगा - जो GetType() विधि सीधे या किसी अन्य तकनीक के माध्यम से उपयोग किया जाता है। यहां कुछ टिप्पणियों के बावजूद is और as ऑपरेटर, और यहां तक ​​कि आधार प्रकार कास्टिंग भी इस मामले में एलएसपी नहीं तोड़ेंगे, क्योंकि उप-वर्ग मूल वर्ग के समान तरीके से मूल्यांकन करेंगे।

+3

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

+0

मैंने सी ++ का उल्लेख किया, क्योंकि मुझे लगा कि यह सी ++ में आरटीटीआई से बाहर निकलना था। मुझे इस मामले में बहुत यकीन है कि यह जानबूझकर नहीं था, हालांकि मैं आपका मुद्दा देखता हूं। –

+0

मैंने सवाल अपडेट किया, क्षमा करें, शायद मैं बहुत स्पष्ट नहीं था। मैं बस क्लाइंट कोड की पहचान कैसे करना चाहता था जो शायद एलएसपी –

उत्तर

4

यदि हम वास्तव में ऐसे मामलों में जहां आप एक विशिष्ट प्रकार के कास्ट करने के लिए डिजाइन बदलकर ज्यादातर मामलों में समस्या हल किया जा सकता की आवश्यकता हो सकती हैं कि पल के लिए उपेक्षा: इस डिजाइन का उपयोग करके

public class Animal 
{ 
    public virtual void Process() 
    { 
     Console.WriteLine("Animal (not a dog)"); 
    } 
} 

public class Dog : Animal 
{ 
    public override void Process() 
    { 
     Console.WriteLine("We have a dog"); 
    } 
} 

var animal = ...; // maybe a Dog, maybe not 
animal.Process(); 
+0

आप सही हैं। मेरे मामले में हालांकि यह कोड डोमेन ऑब्जेक्ट प्रकार के प्रकार के आधार पर UI परत में उचित विज़ार्ड लॉन्च करने वाले कोड के एक टुकड़े से मेल खाता है। मैं वास्तव में इसे बदल नहीं सकता, और यह कोड डोमेन ऑब्जेक्ट में भी नहीं होगा क्योंकि यह यूआई तर्क है। –

+0

स्पष्ट रूप से इसमें से कुछ करता है, क्योंकि यह डोमेन ऑब्जेक्ट पर निर्भर करता है। आप बस 'प्रक्रिया' विधि में 'IWizardLauncher' में पास हो सकते हैं और डोमेन ऑब्जेक्ट ने इसका हिस्सा होने पर इसे आमंत्रित किया है। मैं बस इतना कह रहा हूं कि ऐसे उचित समाधान हैं जो आपके वास्तुकला को तोड़ते नहीं हैं और अभी भी कास्टिंग की आवश्यकता नहीं है। –