मैंने कुछ परियोजनाओं के दौरान अपरिवर्तनीय (रीडोनली) ऑब्जेक्ट्स और अपरिवर्तनीय ऑब्जेक्ट ग्राफ़ बनाने के लिए एक पैटर्न विकसित किया है। अपरिवर्तनीय वस्तुओं को 100% धागा सुरक्षित होने का लाभ होता है और इसलिए धागे में पुन: उपयोग किया जा सकता है। मेरे काम में मैं अक्सर कॉन्फ़िगरेशन सेटिंग्स और अन्य ऑब्जेक्ट्स के लिए वेब अनुप्रयोगों में इस पैटर्न का उपयोग करता हूं जो मैं लोड करता हूं और स्मृति में कैश करता हूं। कैश किए गए ऑब्जेक्ट्स हमेशा अपरिवर्तनीय होना चाहिए क्योंकि आप गारंटी देना चाहते हैं कि वे अप्रत्याशित रूप से परिवर्तित नहीं हुए हैं।सी # में अपरिवर्तनीय वस्तु पैटर्न - आपको क्या लगता है?
अब, आप निश्चित रूप से आसानी से निम्न उदाहरण में अपरिवर्तनीय वस्तुओं डिजाइन कर सकते हैं:
public class SampleElement
{
private Guid id;
private string name;
public SampleElement(Guid id, string name)
{
this.id = id;
this.name = name;
}
public Guid Id
{
get { return id; }
}
public string Name
{
get { return name; }
}
}
यह सरल वर्गों के लिए ठीक है - लेकिन और अधिक जटिल वर्गों के लिए मैं के माध्यम से सभी मान पास करने की अवधारणा पसंद नहीं करते एक निर्माता गुणों पर सेटर्स रखना अधिक वांछनीय है और एक नया ऑब्जेक्ट बनाने वाला आपका कोड पढ़ने में आसान हो जाता है।
तो आप सेटर्स के साथ अपरिवर्तनीय वस्तुएं कैसे बनाते हैं?
ठीक है, मेरे पैटर्न ऑब्जेक्ट्स में पूरी तरह से उत्परिवर्तनीय होने के रूप में शुरू होता है जब तक आप उन्हें एक विधि कॉल के साथ फ्रीज नहीं करते। एक बार ऑब्जेक्ट जमे हुए हो जाने पर यह हमेशा के लिए अपरिवर्तनीय रहेगा - इसे एक म्यूटेबल ऑब्जेक्ट में फिर से नहीं बदला जा सकता है। यदि आपको ऑब्जेक्ट के एक परिवर्तनीय संस्करण की आवश्यकता है, तो आप इसे क्लोन करें।
ठीक है, अब कुछ कोड पर। मेरे पास निम्न कोड स्निपेट्स में पैटर्न को अपने सबसे सरल रूप में उबालने की कोशिश की गई है। आईलेमेंट बेस इंटरफेस है कि सभी अपरिवर्तनीय वस्तुओं को अंततः लागू करना चाहिए।
public class SampleElement : Element
{
private Guid id;
private string name;
public SampleElement() {}
public Guid Id
{
get
{
return id;
}
set
{
FailIfImmutable();
id = value;
}
}
public string Name
{
get
{
return name;
}
set
{
FailIfImmutable();
name = value;
}
}
}
अब आप कर सकते हैं परिवर्तन:
public abstract class Element : IElement
{
private bool immutable;
public bool IsReadOnly
{
get { return immutable; }
}
public virtual void MakeReadOnly()
{
immutable = true;
}
protected virtual void FailIfImmutable()
{
if (immutable) throw new ImmutableElementException(this);
}
...
}
के अपरिवर्तनीय वस्तु पैटर्न लागू करने के लिए ऊपर SampleElement वर्ग refactor करते हैं:
public interface IElement : ICloneable
{
bool IsReadOnly { get; }
void MakeReadOnly();
}
तत्व वर्ग IElement इंटरफेस के डिफ़ॉल्ट कार्यान्वयन है आईडी संपत्ति और नाम संपत्ति जब तक ऑब्जेक्ट को MakeReadOnly() विधि को कॉल करके अपरिवर्तनीय के रूप में चिह्नित नहीं किया गया है। एक बार यह अपरिवर्तनीय हो जाने पर, एक सेटर को कॉल करने से एक अपरिवर्तनीय एलिमेंट अपवाद उत्पन्न होगा।
अंतिम नोट: पूर्ण पैटर्न यहां दिखाए गए कोड स्निपेट से अधिक जटिल है। इसमें अपरिवर्तनीय वस्तुओं के संग्रह और अपरिवर्तनीय ऑब्जेक्ट ग्राफ़ के पूर्ण ऑब्जेक्ट ग्राफ़ के लिए समर्थन भी शामिल है। पूर्ण पैटर्न आपको बाहरी ऑब्जेक्ट पर MakeReadOnly() विधि को कॉल करके एक संपूर्ण ऑब्जेक्ट ग्राफ़ को अपरिवर्तनीय बनाने में सक्षम बनाता है। एक बार जब आप इस पैटर्न का उपयोग करके बड़े ऑब्जेक्ट मॉडल बनाना शुरू कर देते हैं तो लीकी ऑब्जेक्ट्स का खतरा बढ़ जाता है। एक लीकी ऑब्जेक्ट एक ऑब्जेक्ट है जो ऑब्जेक्ट में बदलाव करने से पहले FailIfImmutable() विधि को कॉल करने में विफल रहता है। लीक के लिए परीक्षण करने के लिए मैंने इकाई परीक्षणों में उपयोग के लिए एक सामान्य रिसाव डिटेक्टर कक्षा भी विकसित की है। यह परीक्षण करने के लिए प्रतिबिंब का उपयोग करता है अगर सभी गुण और विधियां अपरिवर्तनीय स्थिति में immutableElementException फेंक देती हैं। दूसरे शब्दों में टीडीडी का उपयोग यहां किया जाता है।
मैं इस पैटर्न को बहुत पसंद करता हूं और इसमें बहुत लाभ प्राप्त करता हूं। तो मैं क्या जानना चाहता हूं कि आप में से कोई भी समान पैटर्न का उपयोग कर रहा है? यदि हां, तो क्या आप किसी भी अच्छे संसाधन के बारे में जानते हैं जो इसे दस्तावेज करता है? मैं अनिवार्य रूप से संभावित सुधारों और किसी भी मानकों के लिए देख रहा हूं जो इस विषय पर पहले से मौजूद हो सकता है।
.NET Framework दिशानिर्देश ILloneable को लागू करने या सार्वजनिक API में इसका उपयोग करने की अनुशंसा नहीं करते हैं, क्योंकि आईसीएलनेबल का अनुबंध अनुबंध को संतुष्ट करने के लिए आवश्यक क्लोन कार्यान्वयन के प्रकार को निर्दिष्ट नहीं करता है। –
यदि आप WPF का उपयोग कर रहे हैं, तो इनमें से अधिकतर फ्रीजबल क्लास से उतरकर पहले ही उपलब्ध है। –
Thx जो - इस कक्षा के बारे में नहीं पता था। बहुत अच्छा लग रहा है। –