दिलचस्प पोस्ट
आराम में लेनदेन? vim change: x फ़ंक्शन को बचाने के बजाय बफर को हटाने के लिए; मान लें कि स्ट्रिंग एक सकारात्मक पूर्णांक है ExecJS और जावास्क्रिप्ट रनटाइम नहीं मिला MySQL त्रुटि 1215: विदेशी कुंजी बाधा नहीं जोड़ सकते एआरसी के बिना @autoreleasepool? पायथन में बाहरी कमांड कॉल करना Git-mv का उद्देश्य क्या है? मैं डेटाएंडटेक्स्ट प्रॉपर्टी का उपयोग कर XAML में एक विंडो पर एक व्यू मॉडेल कैसे सेट करूं? पहला कंपाइलर कैसे लिखा गया था? जावा पूर्णांक अंडरफ्लो और अतिप्रवाह को कैसे संभालता है और आप इसके लिए कैसे जांचेंगे? जावा में एक थ्रेड कैसे शुरू / बंद / पुनरारंभ करें? एक पूर्ण स्क्रीन मोड में शीर्षक छुपा रहा है? JQuery का उपयोग कर एनीमेशन "मैं कृपया प्रतीक्षा करें, लोड हो रहा है …" कैसे बना सकता हूं? jQuery की तारीख पिक्चर- 2 इनपुट / टेक्स्ट बॉक्स और सीमित सीमा

क्या आप एक अच्छा सी # उदाहरण के साथ Liskov प्रतिस्थापन सिद्धांत की व्याख्या कर सकते हैं?

क्या आप सरलीकृत तरीके से सिद्धांत के सभी पहलुओं को कवर करने के लिए एक अच्छा सी # उदाहरण के साथ Liskov प्रतिस्थापन सिद्धांत (ठोस का 'एल') समझा सकते हैं? अगर यह वास्तव में संभव है

वेब के समाधान से एकत्रित समाधान "क्या आप एक अच्छा सी # उदाहरण के साथ Liskov प्रतिस्थापन सिद्धांत की व्याख्या कर सकते हैं?"

(इस उत्तर को पुनः लिखा गया है 2013-05-13, टिप्पणियों के नीचे चर्चा पढ़ें)

एलएसपी आधार वर्ग के अनुबंध का पालन करने के बारे में है।

उदाहरण के लिए आप उप वर्गों में नए अपवाद नहीं फेंक सकते हैं क्योंकि आधार क्लास का इस्तेमाल करने वाली कोई उम्मीद नहीं करेगा। यदि कोई तर्क अनुपलब्ध है और उप वर्ग तर्क को शून्य की अनुमति देता है, तो एक एलएसपी उल्लंघन भी, यदि बेस क्लास ने ArgumentNullException फेंकता है

यहां क्लास स्ट्रक्चर का एक उदाहरण है, जो एलएसपी का उल्लंघन करता है:

 public interface IDuck { void Swim(); // contract says that IsSwimming should be true if Swim has been called. bool IsSwimming { get; } } public class OrganicDuck : IDuck { public void Swim() { //do something to swim } bool IsSwimming { get { /* return if the duck is swimming */ } } } public class ElectricDuck : IDuck { bool _isSwimming; public void Swim() { if (!IsTurnedOn) return; _isSwimming = true; //swim logic } bool IsSwimming { get { return _isSwimming; } } } 

और कॉलिंग कोड

 void MakeDuckSwim(IDuck duck) { duck.Swim(); } 

जैसा कि आप देख सकते हैं, बतख के दो उदाहरण हैं एक कार्बनिक बतख और एक इलेक्ट्रिक बतख अगर बिजली चालू होती है तो बिजली बतख केवल तैर सकता है। यह एलएसपी सिद्धांत को तोड़ता है क्योंकि यह IsSwimming करने के लिए सक्षम होना चाहिए, जैसे कि IsSwimming (जो अनुबंध का हिस्सा भी है) को बेस क्लास के रूप में सेट नहीं किया जाएगा।

आप निश्चित रूप से इस तरह से कुछ करके इसे हल कर सकते हैं

 void MakeDuckSwim(IDuck duck) { if (duck is ElectricDuck) ((ElectricDuck)duck).TurnOn(); duck.Swim(); } 

लेकिन यह ओपन / बंद सिद्धांत को तोड़ देगा और इसे हर जगह लागू किया जाना चाहिए (और इससे भी अस्थिर कोड उत्पन्न होता है)

उचित समाधान स्वचालित रूप से Swim पद्धति में बतख को चालू करना होगा और ऐसा करके इलेक्ट्रिक बतख का व्यवहार ठीक तरह से व्यवहार करेगा जैसा कि IDuck इंटरफ़ेस द्वारा परिभाषित किया गया है

अद्यतन करें

किसी ने एक टिप्पणी जोड़ा और इसे हटा दिया। इसकी एक वैध बात थी कि मुझे पता होना चाहिए:

Swim पद्धति के अंदर बतख को बदलने का समाधान वास्तविक क्रियान्वयन ( ElectricDuck डक) के साथ काम करते समय दुष्प्रभाव हो सकता है। लेकिन एक स्पष्ट इंटरफ़ेस कार्यान्वयन का उपयोग करके इसका समाधान किया जा सकता है। इम्हो यह अधिक संभावना है कि आपको इसे Swim में बदलकर समस्याएं नहीं मिलेंगी क्योंकि यह उम्मीद की जाती है कि जब यह IDuck इंटरफ़ेस का उपयोग करते समय तैर जाएगा

अपडेट 2

इसे और अधिक स्पष्ट करने के लिए कुछ हिस्सों को फिर से दबाएं।

**

एक व्यावहारिक दृष्टिकोण एलएसपी

**

हर जगह मैं एलएसपी के सी # उदाहरण की तलाश करता हूं, लोगों ने काल्पनिक वर्गों और इंटरफेस का इस्तेमाल किया है। यहां एलएसपी का व्यावहारिक कार्यान्वयन है जिसे मैंने अपने सिस्टम में से एक में कार्यान्वित किया है।

परिदृश्य: मान लें कि हमारे पास 3 डाटाबेस हैं (मॉर्टगेज ग्राहक, चालू खाता ग्राहक और बचत खाता ग्राहक) जो ग्राहक डेटा प्रदान करते हैं और हमें दिए गए ग्राहक के अंतिम नाम के लिए ग्राहक के विवरण की आवश्यकता होती है। अब हमें दिए गए अंतिम नाम के खिलाफ उन 3 डेटाबेस से 1 से अधिक ग्राहक विवरण प्राप्त हो सकते हैं।

कार्यान्वयन:

बिजनेस मॉडल लेयर:

 public class Customer { // customer detail properties... } 

डेटा एक्सेस लेयर:

 public interface IDataAccess { Customer GetDetails(string lastName); } 

ऊपर इंटरफ़ेस अमूर्त वर्ग द्वारा लागू किया गया है

 public abstract class BaseDataAccess : IDataAccess { /// <summary> Enterprise library data block Database object. </summary> public Database Database; public Customer GetDetails(string lastName) { // use the database object to call the stored procedure to retirve the customer detials } } 

इस सार वर्ग के पास सभी 3 डेटाबेस के लिए एक सामान्य विधि "GetDetails" है, जिसे नीचे दिखाए गए प्रत्येक डेटाबेस क्लास द्वारा बढ़ाया गया है

MORTGAGE ग्राहक डेटा पहुंच:

 public class MortgageCustomerDataAccess : BaseDataAccess { public MortgageCustomerDataAccess(IDatabaseFactory factory) { this.Database = factory.GetMortgageCustomerDatabase(); } } 

वर्तमान खाता ग्राहक डेटा पहुंच:

 public class CurrentAccountCustomerDataAccess : BaseDataAccess { public CurrentAccountCustomerDataAccess(IDatabaseFactory factory) { this.Database = factory.GetCurrentAccountCustomerDatabase(); } } 

बचत खाता ग्राहक डेटा पहुंच:

 public class SavingsAccountCustomerDataAccess : BaseDataAccess { public SavingsAccountCustomerDataAccess(IDatabaseFactory factory) { this.Database = factory.GetSavingsAccountCustomerDatabase(); } } 

एक बार ये 3 डेटा एक्सेस क्लास सेट हो जाएंगे, अब हम ग्राहक को अपना ध्यान आकर्षित करेंगे। व्यवसाय स्तर में हमारे पास ग्राहक सेवा प्रबंधक वर्ग है जो ग्राहकों को अपने ग्राहकों को हटाए जाने देता है।

बिजनेस लेयर:

 public class CustomerServiceManager : ICustomerServiceManager, BaseServiceManager { public IEnumerable<Customer> GetCustomerDetails(string lastName) { IEnumerable<IDataAccess> dataAccess = new List<IDataAccess>() { new MortgageCustomerDataAccess(new DatabaseFactory()), new CurrentAccountCustomerDataAccess(new DatabaseFactory()), new SavingsAccountCustomerDataAccess(new DatabaseFactory()) }; IList<Customer> customers = new List<Customer>(); foreach (IDataAccess nextDataAccess in dataAccess) { Customer customerDetail = nextDataAccess.GetDetails(lastName); customers.Add(customerDetail); } return customers; } } 

मैंने इसे निर्भर रखने के लिए निर्भरता इंजेक्शन को दिखाया है, क्योंकि यह पहले से ही जटिल हो गया है।

अब अगर हमारे पास एक नया ग्राहक विस्तार डेटाबेस है तो हम सिर्फ एक नया वर्ग जोड़ सकते हैं जो बेसडेटाएव विस्तार करता है और अपने डेटाबेस ऑब्जेक्ट प्रदान करता है।

बेशक हम सभी सहभागी डेटाबेस में समान संग्रहित प्रक्रियाओं की आवश्यकता है

अंत में, ग्राहक सेवा प्रबंधक क्लाइंट के लिए क्लाइंट केवल GetCustomerDetails विधि को कॉल करेगा, अंतिम नाम दर्ज करें और इस बारे में ध्यान नहीं देना चाहिए कि डेटा कैसे से और कैसे आ रहा है।

उम्मीद है कि यह आपको एलएसपी को समझने के लिए एक व्यावहारिक दृष्टिकोण देगा।