ऐसे सदस्यों के साथ वर्ग जो सृजन के दौरान आपस में मिलते-जुलते हैं लेकिन बाद में अपरिवर्तनीय हैं


22

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

एल्गोरिथ्म पूरा होने के बाद, वस्तुओं को कभी नहीं बदला जाना चाहिए - हालांकि वे सॉफ्टवेयर के अन्य भागों द्वारा खपत होती हैं।

इन परिदृश्यों में, क्या कक्षा के दो संस्करणों के लिए अच्छा अभ्यास माना जाता है, जैसा कि नीचे वर्णित है?

  • परिवर्तनशील एक एल्गोरिथ्म द्वारा बनाया गया है, फिर
  • एल्गोरिथ्म के पूरा होने पर, डेटा को अपरिवर्तनीय वस्तुओं में कॉपी किया जाता है जो वापस आ जाते हैं।

3
क्या आप अपनी समस्या को स्पष्ट करने के लिए अपने प्रश्न को संपादित कर सकते हैं?
शमौन Bergot

जवाबों:


46

आप शायद बिल्डर पैटर्न का उपयोग कर सकते हैं । यह आवश्यक डेटा एकत्र करने के उद्देश्य से एक अलग 'बिल्डर' ऑब्जेक्ट का उपयोग करता है, और जब सभी डेटा एकत्र किया जाता है तो यह वास्तविक ऑब्जेक्ट बनाता है। निर्मित वस्तु अपरिवर्तनीय हो सकती है।


आपका समाधान मेरी आवश्यकताओं के लिए सही था (जिनमें से सभी नहीं कहा गया था)। जांच की गई वस्तुओं पर सभी की समान विशेषताएँ नहीं हैं। बिल्डर वर्ग में बहुत सारे अशक्त क्षेत्र होते हैं और जब डेटा का निर्माण किया जाता है, तो वह चुनता है कि कौन सी 3 अलग-अलग कक्षाओं को उत्पन्न करना है: ये विरासत द्वारा एक दूसरे से संबंधित हैं।
पॉल रिचर्ड्स

2
@Paul उस स्थिति में, यदि इस उत्तर ने आपकी समस्या को हल कर दिया है, तो आपको इसे स्वीकार करना चाहिए।
रैलिंग जूल

24

इसे प्राप्त करने का एक सरल तरीका एक इंटरफ़ेस होगा जो किसी को गुणों को पढ़ने और केवल पढ़ने के तरीकों को कॉल करने की अनुमति देता है और एक वर्ग जो उस इंटरफ़ेस को लागू करता है जो आपको उस वर्ग को लिखने की सुविधा देता है।

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

इस उदाहरण को लें:

public interface IPerson 
{
    public String FirstName 
    {
        get;
    }

    public String LastName 
    {
        get;
    }
} 

public class PersonImpl : IPerson 
{
    private String firstName, lastName;

    public String FirstName 
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public String LastName 
    {
        get { return lastName; }
        set { lastName = value; }
    }
}

class Factory 
{
    public IPerson MakePerson() 
    {
        PersonImpl person = new PersonImpl();
        person.FirstName = 'Joe';
        person.LastName = 'Schmoe';
        return person;
    }
}

इस दृष्टिकोण का एकमात्र नुकसान यह है कि कोई इसे लागू करने वाले वर्ग को दे सकता है। यदि यह सुरक्षा का मामला था, तो बस इस दृष्टिकोण का उपयोग करना अपर्याप्त है। इसके लिए एक समाधान यह है कि आप उत्परिवर्तित वर्ग को लपेटने के लिए एक मुखौटा वर्ग बना सकते हैं , जो बस एक इंटरफ़ेस प्रस्तुत करता है जिसके साथ कॉलर काम करता है और आंतरिक ऑब्जेक्ट तक पहुंच नहीं हो सकता है।

इस तरह, कास्टिंग भी आपकी मदद नहीं करेगी। दोनों एक ही पढ़े हुए इंटरफ़ेस से व्युत्पन्न हो सकते हैं, लेकिन लौटी हुई वस्तु को कास्टिंग करने से आपको केवल मुखौटा वर्ग मिलेगा, जो अपरिवर्तनीय है क्योंकि यह लिपटे उत्परिवर्ती वर्ग की अंतर्निहित स्थिति को नहीं बदलता है।

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


1
"केवल पढ़ने के लिए" ऑब्जेक्ट वापस करने से सुरक्षा बेहतर नहीं है, क्योंकि जिस कोड को ऑब्जेक्ट मिलता है, वह अभी भी प्रतिबिंब का उपयोग करके ऑब्जेक्ट को संशोधित कर सकता है। यहां तक ​​कि प्रतिबिंब का उपयोग करके एक स्ट्रिंग को संशोधित किया जा सकता है (नकल नहीं, संशोधित-इन-प्लेस)।
जूल

सुरक्षा समस्या को एक निजी वर्ग के साथ बड़े करीने से हल किया जा सकता है
एबेन स्कोव पेडर्सन

@ ऐसबेन: आपको अभी भी MS07-052 के साथ संघर्ष करना होगा: कोड निष्पादन में कोड निष्पादन परिणाम । आपका कोड उनके कोड के समान सुरक्षा संदर्भ में चल रहा है, इसलिए वे केवल डिबगर संलग्न कर सकते हैं और वे जो चाहें कर सकते हैं।
केविन

केविन 1 आप कह सकते हैं कि सभी एनकैप्सुलेशन के बारे में। मैं प्रतिबिंब से बचाने की कोशिश नहीं कर रहा हूं।
एसेन स्कोव पेडर्सन

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

8

आप वैकल्पिक रूप से बिल्डर पैटर्न का उपयोग कर सकते हैं के रूप में @JacquesB कहते हैं, या लगता है कि यही कारण है कि यह वास्तव में मिलती है कि आपके इन वस्तुओं है है निर्माण के दौरान अस्थायी होने के लिए?

दूसरों के शब्दों में, उन्हें बनाने की प्रक्रिया को समय में फैलाना पड़ता है, क्योंकि निर्माणकर्ता में सभी आवश्यक मूल्यों को पारित करने और एक बार में उदाहरण बनाने का विरोध किया जाता है?

क्योंकि बिल्डर गलत समस्या के लिए एक अच्छा समाधान हो सकता है।

यदि समस्या यह है कि आप एक ऐसे निर्माता के साथ अंत करते हैं जो 10 मापदंडों की तरह लंबा है, और आप इसे कम से कम वस्तु का निर्माण करके इसे कम करना चाहेंगे, तो यह संकेत दे सकता है कि डिजाइन गड़बड़ है, और ये 10 मान होने चाहिए " bagged "/ कुछ वस्तुओं में समूहीकृत ... या मुख्य वस्तु कुछ छोटे लोगों में विभाजित ...

किस मामले में - सभी तरह से अपरिवर्तनीयता के लिए छड़ी, बस डिजाइन में सुधार करें।


डेटा प्राप्त करने के लिए कई डेटाबेस क्वेरीज़ कोड करने के बाद से यह सब एक बार में बनाना मुश्किल होगा; यह विभिन्न तालिकाओं में और विभिन्न डेटाबेस में डेटा की तुलना करता है।
पॉल रिचर्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.