स्टेटिक क्लास और सदस्यों पर विचार और सर्वश्रेष्ठ अभ्यास [बंद]


11

मैं स्थिर सदस्यों या संपूर्ण स्थिर वर्गों के संबंध में विचारों और उद्योग की सर्वोत्तम प्रथाओं के प्रति बहुत उत्सुक हूं। क्या इसमें कोई कमी है, या यह किसी भी विरोधी पैटर्न में भाग लेता है?

मैं इन संस्थाओं को "उपयोगिता वर्ग / सदस्य" के रूप में देखता हूं, इस लिहाज से कि उन्हें कार्यक्षमता प्रदान करने के लिए कक्षा को तत्काल शुरू करने की आवश्यकता या मांग नहीं है।

इस पर सामान्य विचार और उद्योग सर्वोत्तम अभ्यास क्या हैं?

उदाहरण के लिए नीचे दिए गए उदाहरण वर्गों और सदस्यों को देखें कि मैं क्या संदर्भित कर रहा हूं।

// non-static class with static members
//
public class Class1
{
    // ... other non-static members ...

    public static string GetSomeString()
    {
        // do something
    }
}

// static class
//
public static class Class2
{
    // ... other static members ...

    public static string GetSomeString()
    {
        // do something
    }
}

आपका अग्रिम में ही बहुत धन्यवाद!


1
स्टेटिक वर्ग और स्टेटिक तरीके पर MSDN लेख एक बहुत अच्छा इलाज प्रदान करता है।
रॉबर्ट हार्वे

1
@ रोबर्ट हार्वे: हालांकि आपके द्वारा संदर्भित लेख उपयोगी है, यह सर्वोत्तम प्रथाओं के संदर्भ में बहुत कुछ प्रदान नहीं करता है और स्थैतिक कक्षाओं का उपयोग करते समय कुछ नुकसान क्या हैं।
बर्नार्ड

जवाबों:


18

सामान्य तौर पर, स्टैटिक्स से बचें - विशेष रूप से किसी भी प्रकार की स्थिर अवस्था।

क्यों?

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

  2. स्टैटिक्स यूनिट परीक्षण के साथ परेशानी का कारण बनता है। किसी भी इकाई परीक्षण ढांचे के लायक यह नमक समवर्ती परीक्षण करता है। फिर आप # 1 में दौड़ें। इससे भी बुरी बात यह है कि आप अपने परीक्षणों को सभी सेटअप / फाड़ के सामानों के साथ जोड़ते हैं, और जिस हैकरी में आप कोशिश करेंगे और सेटअप कोड "साझा" करेंगे।

बहुत सारी छोटी चीजें भी हैं। स्टैटिक्स अनम्य हो जाते हैं। आप उन्हें इंटरफ़ेस नहीं दे सकते, आप उन्हें ओवरराइड नहीं कर सकते, आप उनके निर्माण के समय को नियंत्रित नहीं कर सकते, आप उन्हें जेनेरिक में अच्छी तरह से उपयोग नहीं कर सकते। आप वास्तव में उन्हें संस्करण नहीं दे सकते।

निश्चित रूप से स्टैटिक्स का उपयोग होता है: निरंतर मूल्य महान काम करते हैं। शुद्ध विधियाँ जो किसी एकल वर्ग में फिट नहीं होती हैं , यहाँ बढ़िया काम कर सकती हैं।

लेकिन सामान्य तौर पर, उनसे बचें।


मैं आपके मतलब के लिए असमर्थता की सीमा तक उत्सुक हूं। क्या आप उस पर विस्तार कर सकते हैं? यदि आपका मतलब है कि सदस्यों को बिना किसी अलगाव के साथ पहुँचा जा सकता है, तो यह सही समझ में आता है। स्टैटिक्स के लिए आपके उपयोग-मामले वही हैं जो मैं आमतौर पर उनके लिए उपयोग करता हूं: निरंतर मूल्य और शुद्ध / उपयोगिता के तरीके। अगर स्टैटिक्स के लिए यह सबसे अच्छा और 99% उपयोग-मामला है, तो इससे मुझे आराम मिलेगा। इसके अलावा, आपके उत्तर के लिए +1। बेहतरीन जानकारी।
थॉमस स्ट्रिंगर

@ThomasStringer - बस इतना है कि थ्रेड / कार्यों के बीच अधिक टचपॉइंट्स का मतलब समवर्ती मुद्दों के लिए अधिक अवसर और / या अधिक प्रदर्शन नुकसान सिंक्रनाइज़ेशन कर रहा है।
तेलस्टिन

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

@ThomasStringer - शायद, शायद नहीं। स्टैटिक्स (अधिकांश भाषाओं में लगभग), इस संबंध में किसी भी अन्य साझा संसाधन से अलग नहीं हैं।
तेलस्टिन

@ThomasStringer: दुर्भाग्य से यह वास्तव में इससे भी बदतर है, जब तक आप सदस्य को चिह्नित नहीं करते volatile। आपको केवल वाष्पशील डेटा के बिना मेमोरी मॉडल से कोई आश्वासन नहीं मिलता है, इसलिए एक धागे में एक चर को बदलना तुरंत या बिल्कुल भी प्रतिबिंबित नहीं हो सकता है।
फॉशी

17

यदि फ़ंक्शन "शुद्ध" है, तो मुझे कोई समस्या नहीं दिखती है। एक शुद्ध कार्य केवल इनपुट मापदंडों में संचालित होता है, और उसी के आधार पर परिणाम प्रदान करता है। यह किसी भी वैश्विक स्थिति या बाहरी संदर्भ पर निर्भर नहीं करता है।

यदि मैं आपके स्वयं के कोड उदाहरण को देखता हूं:

public class Class1
{
    public static string GetSomeString()
    {
        // do something
    }
}

यह फ़ंक्शन कोई पैरामीटर नहीं लेता है। इस प्रकार, यह शायद शुद्ध नहीं है (इस फ़ंक्शन का एकमात्र शुद्ध कार्यान्वयन एक स्थिर लौटना होगा)। मैं मानता हूं कि यह उदाहरण आपकी वास्तविक समस्या का प्रतिनिधि नहीं है, मैं केवल यह इंगित कर रहा हूं कि यह शायद एक शुद्ध कार्य नहीं है।

चलो एक अलग उदाहरण लेते हैं:

public static bool IsOdd(int number) { return (number % 2) == 1; }

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

Telastyn सही रूप से स्थैतिक सदस्यों के साथ एक संभावित समस्या के रूप में संगति का उल्लेख करता है। हालाँकि, चूंकि यह फ़ंक्शन साझा स्थिति का उपयोग नहीं करता है, इसलिए यहां कोई समसामयिक समस्याएं नहीं हैं। एक हजार सूत्र किसी भी संगामिति मुद्दों के बिना एक साथ इस फ़ंक्शन को कॉल कर सकते हैं।

.NET फ्रेमवर्क में, विस्तार विधियाँ काफी समय से मौजूद हैं। LINQ में बहुत सारे विस्तार कार्य हैं (जैसे Enumerable.Where () , Enumerable.First () , Enumerable.Single () , आदि)। हम इन्हें बुरा नहीं मानते, क्या हम?

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

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

तो चलिए इस फ़ंक्शन के लिए क्लाइंट कोड की पठनीयता की जांच करते हैं:

विकल्प (विस्तार विधि के रूप में घोषित फ़ंक्शन के साथ):

public void Execute(int number) {
    if (number.IsOdd())
        // Do something
}

विकल्प b:

public void Execute(int number) {
    var helper = new NumberHelper();
    if (helper.IsOdd(number))
        // Do something
}

स्थैतिक (विस्तार) फ़ंक्शन कोड के पहले टुकड़े को अधिक पठनीय बनाता है, और पठनीयता बहुत मायने रखती है, इसलिए जहां उपयुक्त हो वहां स्थैतिक कार्यों का उपयोग करें।

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