2012-01-03 11 views
5

क्या यह एक अच्छा विचार है कि पूरी तरह प्यारा-फ़ंक्शन-नामकरण कारणों के लिए ओवरलोडिंग का उपयोग करना अच्छा है? :)PHP में गुणों और विधियों को अधिभारित करना - क्या कारण है?

उदाहरण के लिए:

echo $store->product->getPrice($currency);

  • product तो __getObject ('उत्पाद') __get फोन करेगा जो magik सामान करता है और मौजूदा उत्पाद है कि एक वस्तु के रूप में देखा जा रहा है देता है (यह है instantiated अगर यह पहली कॉल है)

echo $store->product('dog')->getPrice($currency);

  • यहाँ product तो __callObject ('उत्पाद', ...) __call फोन करेगा, ...


अधिक भार के बिना विकल्प होगा:

if(!$store->product) 
    $store->product = new Product(); 

echo $store->product->getPrice($currency); 

और

$product = new Product('dog'); 
echo $product->getPrice($currency); 

मुझे वास्तव में अधिभार पसंद है क्योंकि मैं अपनी कक्षाओं के लिए अच्छा एपीआई प्राप्त कर सकता हूं। लेकिन नकारात्मकता यह है कि ओवरलोडेड सामान सीधे गुणों/विधियों को कॉल करने से 15x धीमी है।

क्या इस तरह अधिभार का उपयोग करना ठीक है?

मेरे वर्तमान एप्लिकेशन में मैं अधिभारित सदस्यों को 1000 से अधिक बार कॉल नहीं कर रहा हूं। और इसका प्रदर्शन पर इतना असर नहीं होना चाहिए। हो सकता है कि एक अतिरिक्त 0.1s, जो कि आमतौर पर 0.5-1s में उत्पन्न होता है,

+0

कोड के इस टुकड़े में प्रदर्शन भूमि के ऊपर है कि महत्वपूर्ण नहीं लगता है। लेकिन मैं आमतौर पर बहुत सारे __call और __get विधियों का उपयोग करने से डरता हूं (मान लीजिए कि आप इसे अपने बाकी सॉफ़्टवेयर में उपयोग करने जा रहे हैं) – TFennis

+1

यदि आपका पूरा एपीआई मैजिक मेथड पर निर्भर करता है तो प्रदर्शन प्रभाव महत्वपूर्ण हो सकता है और वहां एक बहुत से लोग जो जादू कोड नापसंद करते हैं क्योंकि यह गैर-स्पष्ट चीजें करता है। – Gordon

उत्तर

3

यह एक अच्छा विचार पूरी तरह से प्यारा-समारोह नामकरण कारणों के लिए अधिक भार का उपयोग करने के है? :)

नहीं। मेरा मतलब है, यह निर्भर करता है। :) चलो हमारे प्रोग्रामिंग जीवन के लिए कुछ बेहतरीन सुविधाएं और मासूमियत जोड़ें:

$ordinary = new stdClass(); 
$ordinary->Caption = 'Hello'; 

class Awesome 
{ 
    private $ordinary; 
    public function __construct($ordinary) { 
     $this->ordinary = (array) $ordinary; 
    } 
    public function __get($name) { 
     $value = ''; 
     return $this->ordinary[$name]; 
    } 
} 

class Lovely extends Awesome 
{ 
    public function __get($name) 
    { 
     return '<3 ' . parent::__get($name) . ' <3'; 
    } 
} 

मैं मानता चाहिए, उदाहरण के शीर्ष पर एक सा हो सकता है, लेकिन कुछ पता चलता है।

सबसे पहले, धारणा यह है कि एपीआई कक्षा के लिए है। तो यह बहुत सामान्य stdClass से शुरू होता है।

क्या उदाहरण तो पता चलता है कि उन जादू कार्यों या कुछ सजाने अधिभार के लिए इस्तेमाल किया जा सकता है। कर सकते हैं, लेकिन नहीं करना चाहिए। भयानक API देखें, यह अपने आप में सिर्फ भयानक है:

$awesome = new Awesome($ordinary); 

echo $awesome->Caption, "\n"; # This caption is just awesome by itself! 
# Hello 

और फिर भी बहुत कुछ सुंदर एपीआई उदाहरण देखें:

$lovely = new Lovely($ordinary); 

echo $lovely->Caption, "\n"; # This caption is lovely, hughs and kisses everyone! 
# <3 Hello <3 
इस उदाहरण में

इसलिए, यह Lovely के लिए एक अच्छा विचार है, लेकिन यह के लिए बेकार है Awesome, क्योंकि Awesome वास्तव में और अधिक प्राप्त करने के लिए आसान है:,

$awesome = $ordinary; 

कौन सा मुझे बात करने के लिए लाता है कि onl एक API में ओवरलोडिंग कर सकते हैं y एक विशिष्ट बिंदु तक उपयोगी हो। Lovely दिखाता है, इसका उपयोग किसी अन्य (अधिक निर्दिष्ट ऑब्जेक्ट) को सजाने के लिए नहीं किया जा सकता है, लेकिन यह भी दिखाता है कि यह केवल एक बार है: Lovely को पहले से ही यह जानना होगा कि Awesome को कॉल करने के लिए इसकी कार्यक्षमता का उपयोग करने के लिए कैसे कॉल करें जादू नहीं किसी भी अब) __get विधि:

public function __get($name) 
    { 
     return '<3 ' . parent::__get($name) . ' <3'; 
    } 

जब आप अब विचार है कि Awesome अपने एपीआई है, तो आप देख सकते हैं कि वह खुद को अन्य coderette यह का उपयोग करने के लिए करना चाहता है कि से आसानी से अतिभारित किया जा करने में सक्षम होने से रोका ।

तो ओवरलोडिंग कंक्रीट कोड में ठीक हो सकती है, और एपीआई को इसे रोकना नहीं चाहिए। लेकिन जब एपीआई स्वयं अधिभारित हो जाती है, तो चीजें मुश्किल हो सकती हैं।

न केवल कोडिंग के लिए, गतिशीलता/जादू जोड़ना चीजों को डीबग करना मुश्किल बनाता है। इसलिए आपके द्वारा बनाए गए एपीआई के लिए बेहतर रहें और अधिक विशिष्ट इंटरफेस प्रदान करें, फिर [] या ->। आप चीजों को ठोस नाम दे सकते हैं और कहा कि अच्छी तरह से काम करता है;)

और यह तब और अधिक सुंदर है:

echo $store->getObject('product')->getPrice($currency); 
3

ओवरलोडिंग का नकारात्मक हिस्सा यह है कि आपको "अच्छा एपीआई" स्वयं का वर्णन करना चाहिए, क्योंकि दस्तावेज़ उपकरण समझ नहीं सकते हैं, क्या आप अपने तरीकों के अंदर करते हैं। एक और मुद्दा यह है कि यह अक्सर "बहुत अधिक जादू" होता है: आप अपने कोड को लागू करने वाले अधिक जादू को समझने के लिए बहुत कठिन बनाते हैं।

दूसरी तरफ मुझे आपके विकल्प के साथ कोई समस्या नहीं दिख रही है। यह मेरी आंखों में भी क्लीनर है।

sidenote: जब तक आप जादू विधियों को लागू नहीं करते हैं, तब तक स्वयं की विधियों की शुरुआत में डबल अंडरस्कोर का उपयोग करने से बचें।

1

भुगतान ऑब्जेक्ट उन्मुख डिजाइन सिद्धांतों का पालन करके प्रदान किए गए लाभों में आता है। पहला उदाहरण कारखाने से उत्पाद वस्तु उत्पन्न करके ढीले युग्मन की अनुमति देता है। OO डिजाइन सिद्धांतों के बारे में अधिक के लिए, देखें S.O.L.I.D. and G.R.A.S.P.

संबंधित मुद्दे

 संबंधित मुद्दे