क्या डेटाटाइप्स के लिए इंटरफेस का उपयोग एक विरोधी पैटर्न है?


9

मान लीजिए कि मेरे मॉडल (ईएफ का उपयोग करके) में विभिन्न इकाइयाँ हैं, उपयोगकर्ता, उत्पाद, चालान और आदेश कहते हैं।

मैं एक उपयोगकर्ता नियंत्रण लिख रहा हूं जो मेरे आवेदन में इकाई वस्तुओं के सारांश को प्रिंट कर सकता है जहां इकाइयां पूर्व-निर्धारित सेट से संबंधित हैं, इस मामले में मैं कहता हूं कि उपयोगकर्ता और उत्पाद का सारांश संक्षेप में प्रस्तुत किया जा सकता है।

सारांश में केवल एक आईडी और एक विवरण होगा, इसलिए मैं इसके लिए एक सरल इंटरफ़ेस बनाता हूं:

 public interface ISummarizableEntity {     
       public string ID { get; }    
       public string Description { get; } 
 }

प्रश्न में संस्थाओं के लिए, मैं एक आंशिक वर्ग बनाता हूं जो इस इंटरफ़ेस को लागू करता है:

public partial class User : ISummarizableEntity
{
    public string ID
    {
        get{ return UserID.ToString(); }
    }

    public string Description 
    {
        get{ return String.Format("{0} {1} is from {2} and is {3} years old", FirstName, LastName, Country, Age); }
    }
}

public partial class Product: ISummarizableEntity
{
    public string ID
    {
        get{ return ProductID.ToString(); }
    }

    public string Description 
    {
        get{ return String.Format("{0} weighs {1}{2} and belongs in the {3} department", ProductName, WeightValue, WeightUnit, Department); }
    }
}

इस तरह मेरा उपयोगकर्ता नियंत्रण / आंशिक दृश्य सिर्फ ISummarizableEntity के किसी भी संग्रह के लिए बाध्य हो सकता है और इसे स्रोत में रुचि रखने की आवश्यकता नहीं है। मुझे बताया गया है कि इंटरफेस का उपयोग डेटाटाइप के रूप में नहीं किया जाना चाहिए, लेकिन मुझे इससे अधिक जानकारी नहीं मिली। जहां तक ​​मैं देख सकता हूं, हालांकि इंटरफेस सामान्य रूप से व्यवहार का वर्णन करते हैं, बस गुणों का उपयोग करना अपने आप में एक विरोधी-पैटर्न नहीं है क्योंकि गुण वैसे भी गेटर्स / सेटर के लिए सिंटैक्टिक चीनी हैं।

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

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


क्या कोई कारण है कि आप इस तरह से कुछ पसंद करते हैं EntitySummary, जैसे Userऔर Productप्रत्येक के पास एक तरीका है public EntitySummary GetSummary()?
बेन आरोनसन

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

@KentAnderson मैं सहमत हूँ। यह इन वर्गों के समग्र इंटरफ़ेस और कैसे उपयोग किया जाता है, इस पर निर्भर करता है कि वास्तव में एक अच्छा विचार हो सकता है या नहीं।
बेन आरोनसन

जवाबों:


17

इंटरफेस व्यवहार का वर्णन नहीं करते हैं। काफी विपरीत, कभी कभी।

इंटरफेस अनुबंधों का वर्णन करते हैं, जैसे "अगर मैं इस ऑब्जेक्ट को किसी भी विधि की पेशकश करने के लिए हूं जो कि एक ISummarizableEntity स्वीकार करता है, तो यह ऑब्जेक्ट एक इकाई होना चाहिए जो खुद को संक्षेप में प्रस्तुत करने में सक्षम हो" - आपके मामले में, जिसे वापस लौटने में सक्षम होने के रूप में परिभाषित किया गया है स्ट्रिंग आईडी और एक स्ट्रिंग विवरण।

यह इंटरफेस का एक सही उपयोग है। कोई विरोधी पैटर्न यहाँ।


2
"इंटरफेस व्यवहार का वर्णन नहीं करते हैं।" "खुद को संक्षेप में कैसे" एक व्यवहार नहीं है?
डोभाल

2
@ थोमस स्ट्रिंगर, वंशानुक्रम, एक ओओ शुद्ध दृष्टिकोण से, एक सामान्य वंश (उदाहरण के लिए, एक वर्ग और एक चक्र दोनों आकृतियाँ हैं ) का अर्थ है । ओपी के उदाहरण में, एक उपयोगकर्ता और एक उत्पाद का कोई साझा सामान्य वंश नहीं है। इस मामले में निहित एक स्पष्ट विरोधी पैटर्न होगा।
केंट ए।

2
@ डोभाल: मुझे लगता है कि इंटरफ़ेस का नाम अपेक्षित व्यवहार का वर्णन कर सकता है। लेकिन यह करने के लिए नहीं है; इंटरफ़ेस को समान रूप से IHasIdAndDescription नाम दिया जा सकता है और उत्तर समान होगा। इंटरफ़ेस स्वयं व्यवहार का वर्णन नहीं करता है, यह अपेक्षाओं का वर्णन करता है।
पीडीआर

2
@pdr अगर आप हेडफोन जैक के जरिए 20V भेजते हैं, तो खराब चीजें होंगी। आकार पर्याप्त नहीं है; उस प्लग के माध्यम से किस तरह के सिग्नल आने वाले हैं इसकी एक बहुत ही वास्तविक और बहुत महत्वपूर्ण अपेक्षा है। ठीक यही कारण है कि इंटरफेस का व्यवहार करने के लिए उनसे जुड़ी विशिष्टताओं का गलत होना गलत नहीं है। Listएक सूची की तरह व्यवहार नहीं करता है कि आप क्या कर सकते हैं ?
डोभाल

3
उपयुक्त इंटरफेस के साथ एक विद्युत प्लग आउटलेट में फिट हो सकता है, लेकिन इसका मतलब यह नहीं है कि यह बिजली (वांछित व्यवहार) का संचालन करेगा।
जेफो

5

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


3
अंतर्संबंधों का वंशानुक्रम से कोई संबंध नहीं है।
डग्म

1
@DougM, शायद मैंने इसे अच्छी तरह से नहीं कहा था, लेकिन मुझे पूरा यकीन है कि हम सहमत हैं।
केंट ए।

1

केवल उन संपत्तियों को ले जाने वाले इंटरफेस को टाला जाना चाहिए :

  • यह इरादे को बाधित करता है: आपको केवल एक डेटा कंटेनर की आवश्यकता है
  • यह विरासत को प्रोत्साहित करता है: संभावना है कि कोई भविष्य में चिंताओं का मिश्रण करेगा
  • यह क्रमबद्धता को रोकता है

यहाँ आप दो चिंताओं का मिश्रण कर रहे हैं:

  • डेटा के रूप में सारांश
  • एक अनुबंध के रूप में सारांश

एक सारांश दो तार से बना है: एक आईडी और एक विवरण। यह सादा डेटा है:

public class Summary {
    private readonly string id;
    private readonly string description;
    public Summary(string id, string description) {
        this.id = id;
        this.description = description;
    }
    public string Id { get { return id; } }
    public string Description { get { return description; } }
}

अब जब आपने परिभाषित किया है कि आप एक अनुबंध को सारांशित करना चाहते हैं, तो आप क्या कर सकते हैं:

public interface ISummarizableEntity {
    public Summary GenerateSummary();
}

ध्यान दें कि गेटर्स में खुफिया का उपयोग करना एक विरोधी पैटर्न है और इसे टाला जाना चाहिए: इसके बजाय कार्यों में स्थित होना चाहिए। यहां बताया गया है कि कार्यान्वयन कैसा दिखता है:

public partial class User : ISummarizableEntity {
    public Summary GenerateSummary() {
        var id = UserID.ToString();
        var description = String.Format("{0} {1} is from {2} and is {3} years old", FirstName, LastName, Country, Age);
        return new Summary(id,description);
    }
}

public partial class Product : ISummarizableEntity {
    public Summary GenerateSummary() {
        var id = ProductID.ToString();
        var description = String.Format("{0} weighs {1}{2} and belongs in the {3} department", ProductName, WeightValue, WeightUnit, Department);
        return new Summary(id,description);
    }
}

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

आप सही हैं मैंने कुछ विवरण जोड़े
वन्ना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.