नाम के रूप में स्थिर वर्गों का उपयोग करना


21

मैंने अन्य डेवलपर्स को नामस्थान के रूप में स्थिर वर्गों का उपयोग करते हुए देखा है

public static class CategoryA
{
    public class Item1
    {
        public void DoSomething() { }
    }
    public class Item2
    {
        public void DoSomething() { }
    }
}

public static class CategoryB
{
    public class Item3
    {
        public void DoSomething() { }
    }
    public class Item4
    {
        public void DoSomething() { }
    }
}

आंतरिक कक्षाओं को तुरंत करने के लिए, यह निम्नलिखित की तरह दिखेगा

CategoryA.Item1 item = new CategoryA.Item1();

तर्क यह है कि नामस्थान "कीवर्ड" का उपयोग करके छिपाया जा सकता है। लेकिन स्थिर वर्गों का उपयोग करके, बाहरी-परत वर्ग के नामों को निर्दिष्ट करना होगा, जो प्रभावी रूप से नामस्थानों को संरक्षित करता है।

Microsoft दिशानिर्देशों में इसके खिलाफ सलाह देता है । मुझे लगता है कि यह पठनीयता को प्रभावित करता है। आपके क्या विचार हैं?


1
यह कार्यान्वयनकर्ता पर निर्भर है कि उन्हें कार्यान्वयन में मौजूद नामस्थानों की आवश्यकता है या नहीं। आप उन पर नामस्थान (और उस पर नकली नामस्थान) के उपयोग को क्यों मजबूर करेंगे?
क्रेगे

समूहों के उद्देश्यों के लिए हो सकता है? जैसे बहुत सारी सब क्लास हैं और सब क्लास को स्टैटिक क्लास में ग्रुप करके। यह बात स्पष्ट है?
user394128

क्या उप-वर्गों को उप-नाम स्थान में रखना भी मंशा को स्पष्ट नहीं करेगा? साथ ही, यह प्रलेखन द्वारा हल की गई समस्या का प्रकार है।
क्रेगे

जवाबों:


16

नामस्थानों के रूप में स्थिर वर्गों का उपयोग करना नामस्थान रखने के उद्देश्य को परिभाषित करता है।

यहाँ महत्वपूर्ण अंतर है:

यदि आप नामस्थान के रूप में परिभाषित करते हैं CategoryA, CategoryB<और जब अनुप्रयोग दो नामस्थान का उपयोग करता है:

CategoryA::Item1 item = new CategoryA::Item1(); 
CategoryB::Item1 item = new CategoryB::Item1();

यदि नामस्थान के बजाय एक स्थिर वर्ग है CategoryAया CategoryBनहीं, तो अनुप्रयोग के लिए उपयोग लगभग ऊपर वर्णित के अनुसार ही है।

हालाँकि, यदि आप इसे एक नाम स्थान के रूप में परिभाषित करते हैं और अनुप्रयोग केवल 1 नाम स्थान (शामिल नहीं करता है CategoryB) का उपयोग करता है , तो उस स्थिति में आवेदन वास्तव में निम्नलिखित का उपयोग कर सकता है

using namespace CategoryA; 
Item1 item = new Item1(); 

लेकिन क्या आपने CategoryAएक स्थिर वर्ग के रूप में परिभाषित किया है जो ऊपर अपरिभाषित है! CategoryA.somethingहर बार एक लिखने के लिए मजबूर किया जाता है।

नामकरण संघर्षों से बचने के लिए नाम स्थान का उपयोग किया जाना चाहिए, जबकि क्लास पदानुक्रम का उपयोग तब किया जाना चाहिए जब क्लास ग्रुपिंग में सिस्टम मॉडल के लिए कुछ प्रासंगिकता हो।


इसके अलावा, अगर कोई भी नेमस्पेस का उपयोग नहीं करना चाहता है, तो भी कैन का उपयोग कर सकता है: using Item1 = CategoryA.Item1(मुझे लगता है कि नेस्टेड क्लास के लिए काम करता है जैसा कि नेमस्पेस के लिए करता है)
जॉर्ज डकेट

1
सी ++ में, एडीएल वर्ग गुंजाइश के साथ काम नहीं करता है; यह नेमस्पेस स्कोप के साथ काम करता है। इसलिए सी ++ में, नाम स्थान न केवल प्राकृतिक विकल्प है, बल्कि सही और मुहावरेदार विकल्प भी है
नवाज

मुझे लगता है कि यह ओपी का इरादा है कि कीवर्ड का उपयोग करके नामस्थान को छिपाने से बचें। वह हर बार उपयोगकर्ताओं को इसे लिखने के लिए बाध्य करना चाहता है। हो सकता है कि उनका नाम स्थान की तरह होvar s = new HideMe.MyPhoneNumberIs12345678.TheRealUsefulClass()
१३:२० पर गक्क्निब

5

जो कुछ भी यहां चल रहा है वह निश्चित रूप से मुहावरेदार नहीं है # कोड।

हो सकता है कि ये अन्य लोग मॉड्यूल पैटर्न को लागू करने की कोशिश कर रहे हों - इससे आपको 'नेमस्पेस' (यानी इस मामले में स्टैटिक क्लास) में फ़ंक्शंस, एक्शन वगैरह भी मिलेंगे?


मैं सहमत हूं, अजीब लगता है।
21

4

सबसे पहले, हर वर्ग एक नाम स्थान पर होना चाहिए, इसलिए आपका उदाहरण वास्तव में अधिक होगा:

SomeNamespace.CategoryA.Item1 item = new SomeNamespace.CategoryA.Item1();

उस ने कहा, मुझे इस तरह के कोड जिमनास्टिक का कोई लाभ नहीं दिखता है जब आप इस तरह के नामस्थान को परिभाषित कर सकते हैं:

namespace SomeNamespace.CategoryA { ... }

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


तो नियम को अपवाद क्यों माना जाता है ?
15:33 बजे sq33G

यह एक अलग सवाल है :) लेकिन मैं अभी भी एक स्थिर वर्ग को परिभाषित नहीं करूंगा, ताकि उसमें शत्रुता को परिभाषित किया जा सके।
zmilojko

1

जावा, जावास्क्रिप्ट और .NET संबंधित नामस्थान पूर्ण नहीं हैं, और केवल कक्षाओं को संग्रहीत करने की अनुमति देते हैं, लेकिन अन्य सामग्री जैसे स्थिरांक या वैश्विक तरीके, नहीं।

कई डेवलपर्स "स्टैटिक क्लासेस" या "स्टैटिक मेथड्स" ट्रिक्स का उपयोग करते हैं, भले ही कुछ लोग सिफारिश न करें।


0

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन एक वर्ग को नाम स्थान (उस पर एक गैर-स्थिर) के रूप में उपयोग करने का एक बहुत ही वैध कारण यह है कि C # पैरामीट्रिक या जेनेरिक नेमस्पेस की परिभाषा का समर्थन नहीं करता है। मैंने यहाँ इस विषय पर एक ब्लॉग पोस्ट लिखी है: http://tyreejackson.com/generics-net-part5-generic-namespaces/

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

बाहरी जेनेरिक क्लास का उपयोग करना और संबंधित प्रकारों को भीतर करना नाटकीय रूप से कोड को कम कर सकता है और इसके अमूर्त को सरल बना सकता है। एक तो एक ठोस कार्यान्वयन के साथ पैरामीट्रिक नाम स्थान वर्ग प्राप्त कर सकता है जो सभी ठोस विवरणों की आपूर्ति करता है।

यहाँ एक तुच्छ उदाहरण है:

public  class   Entity
                <
                    TEntity, 
                    TDataObject, 
                    TDataObjectList, 
                    TIBusiness, 
                    TIDataAccess, 
                    TIdKey
                >
        where   TEntity         : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>, subclassed
        where   TDataObject     : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.BaseDataObject, subclassed
        where   TDataObjectList : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.BaseDataObjectList, subclassed
        where   TIBusiness      : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.IBaseBusiness
        where   TIDataAccess    : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.IBaseDataAccess
{

    public class    BaseDataObject
    {
        public TIdKey Id { get; set; }
    }

    public class BaseDataObjectList : Collection<TDataObject> {}

    public interface IBaseBusiness
    {

        TDataObject     LoadById(TIdKey id);
        TDataObjectList LoadAll();
        void            Save(TDataObject item);
        void            Save(TDataObjectList items);
        void            DeleteById(TIdKey id);
        bool            Validate(TDataObject item);
        bool            Validate(TDataObjectList items);

    }

    public interface IBaseDataAccess
    {

        TDataObject     LoadById(TIdKey id);
        TDataObjectList LoadAll();
        void            Save(TDataObject item);
        void            Save(TDataObjectList items);
        void            DeleteById(TIdKey id);

    }

}

इस तरह इस्तेमाल किया:

public  class   User 
:
                Entity
                <
                    User, 
                    User.DataObject, 
                    User.DataObjectList, 
                    User.IBusiness, 
                    User.IDataAccess, 
                    Guid
                >
{
    public class DataObject : BaseDataObject
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    public class DataObjectList : BaseDataObjectList {}

    public interface IBusiness : IBaseBusiness
    {
        void DeactivateUserById(Guid id);
    }

    public interface IDataAcccess : IBaseDataAccess {}
}

इस तरह से डेरिवेटिव का उपभोग करें:

public class EntityConsumer
{
    private User.IBusiness       userBusiness;
    private Permission.IBusiness permissionBusiness;

    public EntityConsumer(User.IBusiness userBusiness, Permission.IBusiness permissionBusiness) { /* assign dependencies */ }

    public void ConsumeEntities()
    {
        var users       = new User.DataObjectList();
        var permissions = this.permissionBusiness.LoadAll();

        users.Add
        (new User.DataObject()
        {
            // Assign property values
        });

        this.userBusiness.Save(users);

    }
}

इस तरह के प्रकारों को लिखने के लाभ को अमूर्त वर्गों में प्रकार की सुरक्षा और कम कास्टिंग शामिल किया गया है। इसके बड़े पैमाने पर ArrayListबनाम के बराबर है List<T>

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