"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > प्रॉक्सी डिज़ाइन पैटर्न

प्रॉक्सी डिज़ाइन पैटर्न

2024-11-06 को प्रकाशित
ब्राउज़ करें:263

Proxy Design Pattern

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

जावास्क्रिप्ट में प्रॉक्सी डिज़ाइन पैटर्न

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

जावास्क्रिप्ट में, प्रॉक्सी अंतर्निहित हैं विशेषताएं जो प्रॉक्सी ऑब्जेक्ट द्वारा प्रदान की जाती हैं, जो आपको प्रॉपर्टी एक्सेस, असाइनमेंट, फ़ंक्शन इनवोकेशन इत्यादि जैसे मौलिक संचालन के लिए कस्टम व्यवहार को परिभाषित करने की अनुमति देती हैं।

हमें प्रॉक्सी पैटर्न की आवश्यकता कब होती है?

प्रॉक्सी पैटर्न विशेष रूप से तब उपयोगी होता है जब:

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

प्रॉक्सी पैटर्न के घटक

  1. विषय: इंटरफ़ेस जो वास्तविक ऑब्जेक्ट और प्रॉक्सी दोनों के लिए सामान्य संचालन को परिभाषित करता है।
  2. RealSubject: वास्तविक वस्तु जो वास्तविक कार्य करती है।
  3. प्रॉक्सी: मध्यस्थ जो वास्तविक विषय तक पहुंच को नियंत्रित करता है।

सादृश्य:

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

इस सादृश्य में:

  • बड़ी पेंटिंग वास्तविक वस्तु है (एक छवि की तरह जिसे लोड होने में समय लगता है)।
  • पोस्टकार्ड प्रॉक्सी है (एक हल्का विकल्प जो वास्तविक वस्तु तैयार होने तक खड़ा रहता है)।
  • एक बार असली पेंटिंग तैयार हो जाने पर, आप अपने मेहमानों को असली पेंटिंग दिखाते हैं।

वास्तविक-विश्व सादृश्य:

एक रियल एस्टेट एजेंट को एक प्रॉक्सी के रूप में सोचें। जब आप एक घर खरीदना चाहते हैं, तो आप तुरंत हर घर का दौरा नहीं करते (वास्तविक वस्तु को लोड करते हुए)। इसके बजाय, रियल एस्टेट एजेंट (प्रॉक्सी) पहले आपको तस्वीरें और विवरण दिखाता है। केवल जब आप खरीदने के लिए तैयार होते हैं (यानी, जब आप डिस्प्ले() कहते हैं), तो एजेंट घर का दौरा करने की व्यवस्था करता है (वास्तविक वस्तु को लोड करता है)।

वास्तविक दुनिया का उदाहरण: छवि लोडिंग (वर्चुअल प्रॉक्सी)

आइए एक वेब एप्लिकेशन में छवि लोडिंग के उदाहरण का उपयोग करें जहां हम छवि की लोडिंग में तब तक देरी करना चाहते हैं जब तक उपयोगकर्ता इसका अनुरोध नहीं करता (आलसी लोडिंग)। वास्तविक छवि लोड होने तक प्रॉक्सी प्लेसहोल्डर के रूप में कार्य कर सकता है।

यहां बताया गया है कि आप जावास्क्रिप्ट में प्रॉक्सी डिज़ाइन पैटर्न कैसे लागू कर सकते हैं।

उदाहरण: छवि लोड करने के लिए प्रॉक्सी

// Step 1: The real object
class RealImage {
  constructor(filename) {
    this.filename = filename;
    this.loadImageFromDisk();
  }

  loadImageFromDisk() {
    console.log(`Loading ${this.filename} from disk...`);
  }

  display() {
    console.log(`Displaying ${this.filename}`);
  }
}

// Step 2: The proxy object
class ProxyImage {
  constructor(filename) {
    this.realImage = null; // no real image yet
    this.filename = filename;
  }

  display() {
    if (this.realImage === null) {
      // load the real image only when needed
      this.realImage = new RealImage(this.filename);
    }
    this.realImage.display(); // display the real image
  }
}

// Step 3: Using the proxy to display the image
const image = new ProxyImage("photo.jpg");
image.display(); // Loads and displays the image
image.display(); // Just displays the image (already loaded)

स्पष्टीकरण:

1). वास्तविक छवि:

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

2). प्रॉक्सी छवि:

  • ProxyImageclass RealImage के लिए स्टैंड-इन के रूप में कार्य करता है। यह वास्तविक छवि को तुरंत लोड नहीं करता है।
  • इसमें वास्तविक छवि का संदर्भ है (लेकिन शुरुआत में यह शून्य है क्योंकि वास्तविक छवि अभी तक लोड नहीं हुई है)।
  • जब आप प्रॉक्सी पर डिस्प्लेमेथड को कॉल करते हैं, तो यह जांचता है कि वास्तविक छवि लोड की गई है या नहीं। यदि नहीं, तो यह इसे पहले लोड करता है, और फिर प्रदर्शित करता है।

3). उपयोग:

  • जब हम ProxyImage का एक उदाहरण बनाते हैं, तो वास्तविक छवि अभी तक लोड नहीं हुई है (क्योंकि यह संसाधन-गहन है)।
  • पहली बार डिस्प्ले कॉल करने पर, प्रॉक्सी छवि को लोड करता है (RealImageclass का उपयोग करके) और फिर उसे प्रदर्शित करता है।
  • दूसरी बार डिस्प्ले कहा जाता है, वास्तविक छवि पहले ही लोड हो चुकी है, इसलिए यह छवि को दोबारा लोड किए बिना ही प्रदर्शित करता है।

अंतर्निहित प्रॉक्सी ऑब्जेक्ट

ES6 प्रॉक्सी में एक प्रॉक्सी कंस्ट्रक्टर होता है जो लक्ष्य और हैंडलर को तर्क के रूप में स्वीकार करता है

const proxy = new Proxy(target, handler)

यहां, लक्ष्य उस ऑब्जेक्ट का प्रतिनिधित्व करता है जिस पर प्रॉक्सी लागू होती है, जबकि हैंडलर एक विशेष ऑब्जेक्ट है जो प्रॉक्सी के व्यवहार को परिभाषित करता है।

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

आइए अंतर्निर्मित प्रॉक्सी का उपयोग करके कैलकुलेटर लागू करके इसे समझें

// Step 1: Define the Calculator class with prototype methods
class Calculator {
  constructor() {
    this.result = 0;
  }

  // Prototype method to add numbers
  add(a, b) {
    this.result = a   b;
    return this.result;
  }

  // Prototype method to subtract numbers
  subtract(a, b) {
    this.result = a - b;
    return this.result;
  }

  // Prototype method to multiply numbers
  multiply(a, b) {
    this.result = a * b;
    return this.result;
  }

  // Prototype method to divide numbers
  divide(a, b) {
    if (b === 0) throw new Error("Division by zero is not allowed.");
    this.result = a / b;
    return this.result;
  }
}

// Step 2: Create a proxy handler to intercept operations
const handler = {
  // Intercept 'get' operations to ensure access to prototype methods
  get(target, prop, receiver) {
    if (prop in target) {
      console.log(`Accessing property: ${prop}`);
      return Reflect.get(target, prop, receiver); // Access property safely
    } else {
      throw new Error(`Property "${prop}" does not exist.`);
    }
  },

  // Intercept 'set' operations to prevent mutation
  set(target, prop, value) {
    throw new Error(`Cannot modify property "${prop}". The calculator is immutable.`);
  }
};

// Step 3: Create a proxy instance that inherits the Calculator prototype
const calculator = new Calculator(); // Original calculator object
const proxiedCalculator = new Proxy(calculator, handler); // Proxy wrapping the calculator

// Step 4: Use the proxy instance
try {
  console.log(proxiedCalculator.add(5, 3)); // Output: 8
  console.log(proxiedCalculator.multiply(4, 2)); // Output: 8
  console.log(proxiedCalculator.divide(10, 2)); // Output: 5

  // Attempt to access prototype directly through proxy
  console.log(proxiedCalculator.__proto__ === Calculator.prototype); // Output: true

  // Attempt to modify a property (should throw an error)
  proxiedCalculator.result = 100; // Error: Cannot modify property "result".
} catch (error) {
  console.error(error.message); // Output: Cannot modify property "result". The calculator is immutable.
}

इस तरह से प्रॉक्सी का उपयोग करना सबसे अच्छा हिस्सा है:

  • प्रॉक्सी ऑब्जेक्ट को मूल कैलकुलेटर वर्ग का प्रोटोटाइप विरासत में मिला है।
  • प्रॉक्सी के सेट जाल के माध्यम से उत्परिवर्तन से बचा जाता है।

संहिता का स्पष्टीकरण

1). प्रोटोटाइप वंशानुक्रम:

  • प्रॉक्सी **कैलकुलेटर **वर्ग के मूल प्रोटोटाइप में हस्तक्षेप नहीं करता है।
  • इसकी पुष्टि यह जांच कर की जाती है कि क्या proxiedकैलकुलेटर.प्रोटो === कैलकुलेटर.प्रोटोटाइप। परिणाम true होगा।

2). गेटऑपरेशंस को संभालना:

  • गेट ट्रैप प्रॉक्सी ऑब्जेक्ट पर प्रॉपर्टी एक्सेस को रोकता है।
  • हम मूल ऑब्जेक्ट से गुणों और विधियों तक सुरक्षित रूप से पहुंचने के लिए Reflect.get का उपयोग करते हैं।

3). उत्परिवर्तन को रोकना:

जब भी लक्ष्य ऑब्जेक्ट पर किसी संपत्ति को संशोधित करने का प्रयास किया जाता है तो सेट ट्रैप एक त्रुटि फेंकता है। यह अपरिवर्तनीयता सुनिश्चित करता है।

4). प्रॉक्सी के माध्यम से प्रोटोटाइप विधियों का उपयोग करना:

प्रॉक्सी जोड़ने, घटाने, गुणा करने और विभाजित करने जैसी विधियों तक पहुंच की अनुमति देता है, जो सभी मूल ऑब्जेक्ट के प्रोटोटाइप पर परिभाषित हैं।

यहां ध्यान देने योग्य मुख्य बिंदु हैं:

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

यदि आप यहां तक ​​पहुंच गए हैं, तो लाइक ❤️ दबाना न भूलें और किसी भी प्रश्न या विचार के लिए नीचे टिप्पणी करना न भूलें। आपकी प्रतिक्रिया मेरे लिए बहुत मायने रखती है, और मुझे आपसे सुनना अच्छा लगेगा!

विज्ञप्ति वक्तव्य यह लेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/srishtikप्रसाद/proxy-design-pattern-4mm?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3