तो मान लीजिए कि आप पर्यवेक्षक पैटर्न नहीं चाहते हैं क्योंकि यह आवश्यक है कि आप सुनने के कार्य को संभालने के लिए अपनी कक्षा विधियों को बदल दें, और कुछ सामान्य बनाना चाहते हैं। और मान लीजिए कि आप विस्तार
विरासत का उपयोग नहीं करना चाहते हैं क्योंकि आप पहले से ही किसी अन्य वर्ग से अपनी कक्षा में विरासत में हो सकते हैं। किसी भी वर्ग को बिना किसी प्रयास के प्लग करने योग्य बनाने के लिए एक सामान्य तरीका होना अच्छा नहीं होगा ? ऐसे:
<?php
////////////////////
// PART 1
////////////////////
class Plugin {
private $_RefObject;
private $_Class = '';
public function __construct(&$RefObject) {
$this->_Class = get_class(&$RefObject);
$this->_RefObject = $RefObject;
}
public function __set($sProperty,$mixed) {
$sPlugin = $this->_Class . '_' . $sProperty . '_setEvent';
if (is_callable($sPlugin)) {
$mixed = call_user_func_array($sPlugin, $mixed);
}
$this->_RefObject->$sProperty = $mixed;
}
public function __get($sProperty) {
$asItems = (array) $this->_RefObject;
$mixed = $asItems[$sProperty];
$sPlugin = $this->_Class . '_' . $sProperty . '_getEvent';
if (is_callable($sPlugin)) {
$mixed = call_user_func_array($sPlugin, $mixed);
}
return $mixed;
}
public function __call($sMethod,$mixed) {
$sPlugin = $this->_Class . '_' . $sMethod . '_beforeEvent';
if (is_callable($sPlugin)) {
$mixed = call_user_func_array($sPlugin, $mixed);
}
if ($mixed != 'BLOCK_EVENT') {
call_user_func_array(array(&$this->_RefObject, $sMethod), $mixed);
$sPlugin = $this->_Class . '_' . $sMethod . '_afterEvent';
if (is_callable($sPlugin)) {
call_user_func_array($sPlugin, $mixed);
}
}
}
} //end class Plugin
class Pluggable extends Plugin {
} //end class Pluggable
////////////////////
// PART 2
////////////////////
class Dog {
public $Name = '';
public function bark(&$sHow) {
echo "$sHow
\n";
}
public function sayName() {
echo "
\nMy Name is: " . $this->Name . "
\n";
}
} //end class Dog
$Dog = new Dog();
////////////////////
// PART 3
////////////////////
$PDog = new Pluggable($Dog);
function Dog_bark_beforeEvent(&$mixed) {
$mixed = 'Woof'; // Override saying 'meow' with 'Woof'
//$mixed = 'BLOCK_EVENT'; // if you want to block the event
return $mixed;
}
function Dog_bark_afterEvent(&$mixed) {
echo $mixed; // show the override
}
function Dog_Name_setEvent(&$mixed) {
$mixed = 'Coco'; // override 'Fido' with 'Coco'
return $mixed;
}
function Dog_Name_getEvent(&$mixed) {
$mixed = 'Different'; // override 'Coco' with 'Different'
return $mixed;
}
////////////////////
// PART 4
////////////////////
$PDog->Name = 'Fido';
$PDog->Bark('meow');
$PDog->SayName();
echo 'My New Name is: ' . $PDog->Name;
भाग 1 में, आप अपनी PHP स्क्रिप्ट के शीर्ष पर requ_once()
कॉल के साथ शामिल हो सकते हैं। यह कुछ प्लग करने योग्य बनाने के लिए कक्षाओं को लोड करता है।
भाग 2 में, वहीं हम एक वर्ग लोड करते हैं। नोट मुझे कक्षा के लिए विशेष कुछ भी करने की ज़रूरत नहीं है, जो पर्यवेक्षक पैटर्न से काफी अलग है।
भाग 3 में, वहीं हम अपनी कक्षा को "प्लग करने योग्य" होने के लिए स्विच करते हैं (यानी, प्लगइन का समर्थन करता है जो हमें क्लास विधियों और गुणों को ओवरराइड करने देता है)। इसलिए, उदाहरण के लिए, यदि आपके पास कोई वेब ऐप है, तो आपके पास प्लगइन रजिस्ट्री हो सकती है, और आप यहां प्लगइन सक्रिय कर सकते हैं। ध्यान दें Dog_bark_beforeEvent()
फ़ंक्शन। यदि मैं रिटर्न स्टेटमेंट से पहले $ मिश्रित = 'BLOCK_EVENT'
सेट करता हूं, तो यह कुत्ते को भौंकने से रोक देगा और Dog_bark_afterEvent को भी अवरुद्ध करेगा क्योंकि कोई ईवेंट नहीं होगा।
भाग 4 में, यह सामान्य ऑपरेशन कोड है, लेकिन ध्यान दें कि जो भी आप सोच सकते हैं वह दौड़ना उतना ही नहीं चलता है। उदाहरण के लिए, कुत्ता इसका नाम 'फिडो', लेकिन 'कोको' के रूप में घोषित नहीं करता है। कुत्ता 'मेयो' नहीं कहता है, लेकिन 'वाह'। और जब आप कुत्ते के नाम को बाद में देखना चाहते हैं, तो आपको लगता है कि यह 'कोको' के बजाय 'अलग' है। उन सभी ओवरराइड भाग 3 में प्रदान किए गए थे।
यह कैसे काम करता है? खैर, आइए eval()
(जो हर कोई कहता है "बुराई" है) और नियम दें कि यह पर्यवेक्षक पैटर्न नहीं है। तो, जिस तरह से यह काम करता है वह स्नेकी खाली वर्ग है जिसे प्लग्गेबल कहा जाता है, जिसमें कुत्ते वर्ग द्वारा उपयोग की जाने वाली विधियों और गुणों में शामिल नहीं है। इस प्रकार, चूंकि ऐसा होता है, जादू विधियां हमारे लिए संलग्न होंगी। यही कारण है कि भागों 3 और 4 में हम प्लग करने योग्य वर्ग से प्राप्त वस्तु के साथ गड़बड़ करते हैं, न कि कुत्ते वर्ग स्वयं। इसके बजाए, हमने प्लगइन क्लास को हमारे लिए डॉग ऑब्जेक्ट पर "स्पर्श" करने दिया। (यदि यह किसी प्रकार का डिज़ाइन पैटर्न है, तो मुझे पता नहीं है - कृपया मुझे बताएं।)