मुझे पहले से मौजूद किसी ऑब्जेक्ट में कार्यक्षमता कैसे जोड़नी चाहिए?


25

मेरे पास एक इंटरफ़ेस है जिसमें एक निश्चित मात्रा में अच्छी तरह से परिभाषित कार्यक्षमता है। हम कहते हैं:

interface BakeryInterface {
  public function createCookies();
  public function createIceCream();
}

यह इंटरफ़ेस के अधिकांश कार्यान्वयन के लिए अच्छी तरह से काम करता है, लेकिन कुछ उदाहरणों में, मुझे कुछ नई कार्यक्षमता जोड़ने की आवश्यकता है (जैसे शायद एक नई पद्धति में लुढ़का हुआ है createBrownies())। ऐसा करने के लिए स्पष्ट / भोली दृष्टिकोण इंटरफ़ेस का विस्तार करना होगा:

interface BrownieBakeryInterface extends BakeryInterface {
  public function createBrownies();
}

लेकिन इसमें एक बहुत बड़ा नकारात्मक पहलू यह है कि मैं मौजूदा API को संशोधित किए बिना नई कार्यक्षमता को नहीं जोड़ सकता (जैसे कि नए इंटरफ़ेस का उपयोग करने के लिए कक्षा को बदलना)।

मैं तात्कालिकता के बाद कार्यक्षमता जोड़ने के लिए एक एडेप्टर का उपयोग करने के बारे में सोच रहा था :

class BrownieAdapter {
  private brownieBakery;

  public function construct(BakeryInterface bakery) {
    this->brownieBakery = bakery;
  }

  public function createBrownies() {
    /* ... */
  }
}

जो मुझे कुछ इस तरह शुद्ध करेगा:

bakery = new Bakery();
bakery = new BrownieBakery(bakery);
bakery->createBrownies();

यह समस्या का एक अच्छा समाधान लगता है, लेकिन मैं सोच रहा हूं कि क्या मैं पुराने देवताओं को जागृत कर रहा हूं। क्या एडॉप्टर जाने का रास्ता है? वहाँ एक बेहतर पैटर्न का पालन करने के लिए है? या क्या मुझे वास्तव में सिर्फ बुलेट को काट देना चाहिए और सिर्फ मूल इंटरफ़ेस का विस्तार करना चाहिए?


डेल्फी में सहायक कक्षाएं हैं, यह मौजूदा कक्षाओं में तरीकों को जोड़ने के बिना है, वास्तव में उन्हें संशोधित किए बिना। उदाहरण के लिए डेल्फी के पास अपनी ग्राफिक्स इकाई में परिभाषित एक टीबीटैम्प श्रेणी है, आप एक सहायक वर्ग बना सकते हैं जो कहते हैं, कहते हैं, टीबीटैम्प में एक फ्लिप फ़ंक्शन। जब तक हेल्पर क्लास स्कोप है तब तक आप MyBitmap.Flip पर कॉल कर सकते हैं;
बिल

जवाबों:


14

हैंडल बॉडी पैटर्न में से कोई भी आपकी सटीक आवश्यकताओं, भाषा और अमूर्तता के आवश्यक स्तर के आधार पर विवरण को फिट कर सकता है।

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


यह वही है जो मुझे चाहिए था: मुझे एहसास हुआ कि एडेप्टर के उपयोग से निर्भरता इंजेक्शन के साथ खराब हो जाएगी, लेकिन एक डेकोरेटर का उपयोग करने से यह चारों ओर हो जाता है।

5

की अवधारणा की जांच क्षैतिज पुन: उपयोग , जहां इस तरह के रूप सामान मिल सकता है लक्षण , अभी भी प्रयोगात्मक लेकिन पहले से ही उत्पादन प्रूफ पहलू उन्मुख प्रोग्रामिंग और कभी कभी नफरत mixins

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

var MyClass = {
    do : function(){...}
};

var MyNewClass = new MyClass;
MyClass.undo = function(){...};


var my_new_object = new MyNewClass;
my_new_object.do();
my_new_object.undo();

अंत में, आप प्रतिबिंब के साथ क्षैतिज पुन: उपयोग, या रनटाइम "संशोधन" और वर्ग / वस्तु व्यवहार के "जोड़" का भी अनुकरण कर सकते हैं ।


4

यदि कोई आवश्यकता है कि bakeryउदाहरण को अपने व्यवहार को गतिशील रूप से बदलना होगा (उपयोगकर्ता कार्यों, आदि के आधार पर) तो आपको डेकोरेटर पैटर्न के लिए जाना चाहिए ।

यदि bakeryइसका व्यवहार गतिशील रूप से नहीं बदलता है, लेकिन आप Bakery class(बाहरी एपीआई, आदि) को संशोधित नहीं कर सकते हैं तो आपको एडॉप्टर पैटर्न के लिए जाना चाहिए ।

तो bakeryगतिशील रूप से अपने व्यवहार में परिवर्तन नहीं होता है और आप संशोधित कर सकते हैं Bakery classतो आप मौजूदा इंटरफ़ेस का विस्तार करना चाहिए (के रूप में आप शुरू में प्रस्तावित) या एक परिचय नए इंटरफ़ेस BrownieInterface और जाने Bakeryदो इंटरफेस को लागू BakeryInterfaceऔर BrownieInterface
अन्यथा आप बिना किसी अच्छे कारण के अपने कोड (डेकोरेटर पैटर्न का उपयोग करके) में अनावश्यक जटिलता जोड़ने जा रहे हैं!


2

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

क्रिस हाउसर की यह प्रस्तुति भी है जो एक ही मैदान पर बहुत चर्चा करती है।

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