2012-09-17 23 views
18

बिना मैं हाल ही में एक अंतरफलक में आए कि केवल इसलिए की तरह एक सेटर परिभाषित:इंटरफ़ेस: सेटर एक मनुष्य

public interface IAggregationView 
{ 
    DataTable SetSiteData { set; } 
} 

मैं इस पूछे, और यह माना जाता है कि इस प्रथाओं WebPart के लिए माइक्रोसॉफ्ट द्वारा की वकालत में से एक है डिजाइन (शेयरपॉइंट के लिए)। वास्तव में यह उदाहरण सीधे उनके उदाहरणों से कॉपी किया गया है।

मैं इसे एक खराब पैटर्न के रूप में देखता हूं, मुझे नहीं लगता कि किसी को मूल्य निर्धारित करने में सक्षम क्यों होना चाहिए, और फिर इसे फिर से पढ़ने में सक्षम नहीं होना चाहिए, और मेरा मानना ​​है कि एक सेटर हमेशा एक गेटर के साथ होना चाहिए (लेकिन जरूरी नहीं कि दूसरी तरफ)।

मुझे आश्चर्य है कि कोई भी केवल एक सेटटर होने के लाभ की व्याख्या कर सकता है, क्यों माइक्रोसॉफ्ट इस मामले में इसका सुझाव दे रहा है, और यदि यह वास्तव में पालन करने के लिए एक अच्छा पैटर्न है?

+0

मुझे लगता है कि यह एक सेटटर प्रदान नहीं करने जैसा ही होगा। उस मामले में सेटटर डिफ़ॉल्ट रूप से निजी सेट है। शायद गेटटर के लिए भी वही। –

+4

यदि डुप्लिकेट नहीं है तो संबंधित हो सकता है: http://stackoverflow.com/questions/4695551/write-only-properties-whats-the-point – Habib

+1

यह निश्चित रूप से असामान्य पैटर्न है; जैसा कि 'सेट ...' उपसर्ग के साथ एक संपत्ति का नामकरण कर रहा है। –

उत्तर

20

दो स्थितियों रहे हैं मैं देख सकता हूँ, जहां इस उचित हो सकता है:

  1. यह नहीं है संभव प्राप्त मूल्य, उदाहरण के पासवर्ड के लिए; हालांकि, मुझे लगता है कि जगह लेंगे एक void SetPassword(string) विधि के साथ, व्यक्तिगत रूप से
  2. एपीआई यह लिए बनाया गया है कोई आवश्यकता कभी मूल्य को पढ़ने के लिए है, और यह विशुद्ध रूप से न्यूनतम आवश्यक एपीआई

बेनकाब करने के लिए प्रतिबंधित किया जा रहा है मेरा पहला बिंदु, Set...विधि आदर्श नहीं हो सकता है यदि उपभोग करने वाला एपीआई अनिवार्य रूप से एक स्वचालित मैपर है जो गुणों को मान निर्दिष्ट करता है; उस परिदृश्य में गुण वास्तव में बेहतर होगा।

अपने "मैं नहीं देखता कि किसी को मूल्य निर्धारित करने में सक्षम क्यों होना चाहिए, और फिर इसे फिर से पढ़ने में सक्षम नहीं होना चाहिए" - एक ही बिंदु से, हालांकि, यह तर्क दिया जा सकता है कि कोई व्यक्ति पहले से ही (वे इसे सेट करते हैं) को जानते हैं, इसलिए ऐसा करने के लिए उनके पास आवश्यकता नहीं है।

लेकिन हाँ; केवल एकमात्र संपत्ति होना बहुत असामान्य है।

+0

मुझे आपका पासवर्ड उदाहरण वास्तव में पसंद है, यह एक अच्छा स्पष्ट मामला है कि आप कहां ऐसा करना चाहते हैं, लेकिन व्यक्तिगत रूप से एक विधि का चयन भी करेगा। अच्छा उत्तर। – Ian

+0

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

+0

@DanielEarwicker हाँ, लेकिन जब इंटरफ़ेस एपीआई कक्षा के सार्वजनिक एपीआई का प्रत्यक्ष सबसेट नहीं है, तो हमेशा * स्पष्ट इंटरफ़ेस कार्यान्वयन * –

1

मेरे अनुभवों में ऐसे इंटरफेस कुछ विशेष आवश्यकता के कारण फसल बनते हैं, वास्तुशिल्प कारणों से नहीं। उदाहरण के लिए एएसपी.नेट अनुप्रयोगों में लोग कभी-कभी ग्लोबल.एक्सएक्स जेनरेट प्रकार को ऐसे इंटरफ़ेस से प्राप्त करते हैं जब वे वैश्विक स्थिति को बनाए रखना चाहते हैं। कोई भी एप्लिकेशन के एक अलग हिस्से में प्रारंभिक मान बना सकता है और इसे वैश्विक स्थान पर प्रकाशित करने की आवश्यकता है।

मैं आमतौर पर एक सेट-केवल संपत्ति को SetXxx विधि से प्रतिस्थापित करना चाहता हूं और विधि को जांचता हूं कि इसे सबसे अधिक बार बुलाया जाता है। इस तरह से मैं स्पष्ट रूप से "प्रारंभिक शैली" को लागू करता हूं जो एक गंध (इमो) से बहुत कम है।

निश्चित रूप से पर सेट नहीं किया जा सकता है ऐसी चीज उत्पन्न करता है लेकिन इसे टालना है और निश्चित रूप से कोड समीक्षा के दौरान प्रश्न उठाएगा।

2

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

एक इंटरफेस केवल "परमाणु रूप से आवश्यक" संचालन के समूह को घोषित करने की सुविधा है (उदाहरण के लिए यदि आपको विधि ए को कॉल करने की आवश्यकता है, तो आपको संपत्ति बी को पढ़ने और संपत्ति सी सेट करने की आवश्यकता होगी)।

तो हमेशा के रूप में, यह पर निर्भर करता है।

14

इंटरफेस गुणों में get और set की भूमिका कक्षाओं में से थोड़ा अलग है।

public interface IAggregationView 
{ 
    DataTable SetSiteData { set; } 
} 

class AggregationViewImp : IAggregationView 
{ 
    public DataTable SetSiteData { get; set; } // perfectly OK 
} 

इंटरफेस निर्दिष्ट करता है कि संपत्ति कम से कम एक सार्वजनिक सेटर होना चाहिए। गेटटर की परिभाषा और अभिगम्यता कार्यान्वयन वर्ग को छोड़ दी गई है।

तो अगर इंटरफ़ेस अनुबंध को केवल लिखने की आवश्यकता है, get को छोड़ा जा सकता है। सार्वजनिक गेटर की मांग करने की कोई ज़रूरत नहीं है।

परिणामस्वरूप, आप वास्तव में इंटरफेस में केवल पढ़ने-योग्य संपत्ति निर्दिष्ट नहीं कर सकते हैं। केवल 'कम से कम पढ़ने का उपयोग करें'।

interface IFoo 
{ 
    int Id { get; } 
} 

class Foo : IFoo 
{ 
    public int Id { get; set; } // protected/private set is OK too 
} 
+0

मेरे से अधिक स्पष्ट, और कोड उदाहरणों के साथ +1। –

+0

उतना ही महत्वपूर्ण रूप से "फू" * आंतरिक * है, इस प्रकार कार्यान्वयन को इसके तत्काल दायरे में ठीक से encapsulating। –

4

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

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