2010-02-03 21 views
6

उदाहरण दिखाने के लिए यह प्रश्न क्या है:एकाधिक कक्षाओं द्वारा उपयोग की जाने वाली विधियों को कहां रखा जाए?

मुझे वर्तमान में PHP प्रोजेक्ट में एक दुविधा है जो मैं काम कर रहा हूं। मुझे एक विधि है जो कई वर्गों (इस मामले में यूआई - एमवीसी मॉडल) द्वारा उपयोग की जाएगी, लेकिन मुझे यकीन नहीं है कि ओओ डिज़ाइन में ऐसे तरीकों का प्रतिनिधित्व कैसे किया जाए। पहली बात जो मेरे दिमाग में आई थी वह स्थिर कार्य के साथ एक वर्ग बनाना था जिसे मैं कभी भी कॉल करता हूं। हालांकि मुझे यकीन नहीं है कि यह सही काम है या नहीं।

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

कुछ लोग कह सकते हैं कि मुझे इसके लिए कक्षा का उपयोग नहीं करना चाहिए, क्योंकि PHP में भी मैं अभी भी कर सकता हूं प्रक्रियात्मक कोड का प्रयोग करें। लेकिन मुझे जवाब में अधिक दिलचस्पी है जो मुझे ओओपी/ओओडी में ऐसी परिस्थितियों तक पहुंचने के लिए प्रेरित करेगी।

तो वास्तविक प्रश्न हैं: ऐसी विधियों का प्रतिनिधित्व कैसे करें? क्या स्थिर कार्य दृष्टिकोण पर्याप्त है या क्या मुझे किसी और चीज पर पुनर्विचार करना चाहिए?

+0

यदि कक्षाएं किसी IS_A संबंध से संबंधित हैं तो आपको केवल एक विरासत दृष्टिकोण का उपयोग करना चाहिए। अन्यथा एक मॉड्यूल का उपयोग करें। –

उत्तर

5

मैं इस व्यवहार को शामिल करने वाली सामान्य श्रेणी बनाने की अनुशंसा करता हूं, और उसके बाद कक्षा को सदस्यों के सदस्यों से निकाले गए इंटरफ़ेस को लागू करने दें।

जब भी आपको उन तरीकों को कॉल करने की आवश्यकता होती है, तो आप उपभोक्ता में इंटरफ़ेस (कंक्रीट क्लास नहीं) इंजेक्ट करते हैं। यह आपको एक दूसरे के स्वतंत्र रूप से दो अलग-अलग करने देता है।

यह अधिक काम की तरह लग सकता है, लेकिन बस Strategy डिज़ाइन पैटर्न लागू है।

इससे कोड की जांच करने के लिए इकाई को अधिक आसान बना दिया जाएगा, क्योंकि कोड अधिक ढीला युग्मित है।


यहां सी # में एक उदाहरण है।

इंटरफ़ेस:

public interface ITimeMachine 
{ 
    IStopwatch CreateStopwatch(); 

    DateTimeOffset GetNow(); 
} 

उत्पादन कार्यान्वयन:

public class RealTimeMachine : ITimeMachine 
{ 
    #region ITimeMachine Members 

    public IStopwatch CreateStopwatch() 
    { 
     return new StopwatchAdapter(); 
    } 

    public DateTimeOffset GetNow() 
    { 
     return DateTimeOffset.Now; 
    } 

    #endregion 
} 

और यहाँ इंटरफ़ेस का एक उपभोक्ता है:

public abstract class PerformanceRecordingSession : IDisposable 
{ 
    private readonly IStopwatch watch; 

    protected PerformanceRecordingSession(ITimeMachine timeMachine) 
    { 
     if (timeMachine == null) 
     { 
      throw new ArgumentNullException("timeMachine"); 
     }   

     this.watch = timeMachine.CreateStopwatch(); 
     this.watch.Start(); 
    } 

    public abstract void Record(long elapsedTicks); 

    public virtual void StopRecording() 
    { 
     this.watch.Stop(); 
     this.Record(this.watch.ElapsedTicks); 
    } 
} 
+0

इसका मतलब है कि मुझे इन कार्यों में से प्रत्येक के लिए कस्टम फ़ंक्शंस + कक्षा को संभालने के लिए कक्षा बनाना चाहिए और फिर बस निष्पादित करें()? इसलिए, उदाहरण के लिए, "टाइम टॉस्ट्रिंग" फ़ंक्शन निष्पादित() फ़ंक्शन, इंटरफेस को कार्यान्वित करने के साथ एक अलग वर्ग बन जाएगा। और मैं इसे नए कस्टमफंक्शन (नया टाइम टॉस्ट्रिंग) के माध्यम से कॉल करूंगा; ... $ custom_function-> निष्पादित करें()? क्या यह रणनीति पैटर्न कैसे काम करता है या क्या मैं इस अवधारणा को गलत समझता हूं? क्या यह हर एक समारोह के लिए मूल रूप से कक्षा बनाने के लिए थोड़ा अधिक नहीं है? –

+0

आपको प्रत्येक फ़ंक्शन के लिए कक्षा बनाने की आवश्यकता नहीं है। आप एक ही कक्षा में संबंधित परिचालनों को बंडल कर सकते हैं। यही सब कुछ है, आखिरकार encapsulation और छत क्या है। उन परिचालनों को सभी एक ही इंटरफ़ेस पर परिभाषित किया जा सकता है, इस प्रकार आपको एक बंडल में संचालन के एक एकल संयोजन सेट को पास करने की क्षमता प्रदान की जा सकती है। –

+0

क्या आप कृपया अपनी पोस्ट को एक संक्षिप्त उदाहरण (किसी भी भाषा में) संपादित कर सकते हैं? जैसा कि मैं अभी भी यह समझने में असफल रहा कि यह कैसे करना है। क्या मुझे बस कई कार्यों के साथ एक वर्ग बनाना चाहिए, सदस्यों से निकाले गए इंटरफ़ेस को कार्यान्वित करना चाहिए और फिर इस इंटरफ़ेस को इंजेक्ट करना चाहिए जहां मुझे इसकी आवश्यकता हो और उन सभी कार्यों को इसके माध्यम से कॉल करें? मुझे लगता है कि मुझे क्या भ्रमित करता है कि आपने रणनीति पैटर्न का उल्लेख किया है और मैं इसके द्वारा समाधान को लागू करने की कोशिश कर रहा हूं। मुझे यह भी समझ में नहीं आता कि मेरे पास एक इंटरफ़ेस क्यों होगा जो केवल एक वर्ग द्वारा लागू किया गया है। ठोस वर्ग को बुलाकर तंग कपलिंग को रोकने के लिए? –

0

नामस्थान के रूप में कक्षा का उपयोग करें। तो हाँ, एक स्थिर वर्ग है।

class Time { 
    public static function getCurrentTime() { 
     return time() + 42; 
    } 
} 
+3

स्टेटिक क्लास = तंग युग्मन –

+0

@ सिमैन, मैं "सही" और "उचित" समाधानों के लिए आसान पसंद करता हूं (हाँ, मैं कभी-कभी एक पागलपन का कुछ हद तक ...)। अगर मुझे बाद में "सामान्य" कक्षा बनाने की ज़रूरत है, तो मैं इसे करने के लिए कोड को आसानी से दोबारा कर सकता हूं। अन्यथा, यह बर्बाद समय है, आईएमओ। – strager

0

मैं PHP नहीं करता, लेकिन ओओ बिंदु से, स्थिरता विधियों के रूप में उपयोगिता विधियों के इस प्रकार को ठीक करना ठीक है। अगर वे प्रकृति में पूरी तरह से पुन: प्रयोज्य हैं, तो उन्हें एक यूटिल क्लास में रखने पर विचार करें।

+1

स्टेटिक क्लास = तंग युग्मन –

+0

ऐसा नहीं है कि मैं आईओसी/डीपी इंजेक्शन की सराहना नहीं करता हूं, लेकिन इस उदाहरण में, जहां एक विधि कुछ समय के साथ सीधी और गैर-विस्तारणीय के रूप में कार्य करती है, तो संकेत का एक और स्तर बनाने के लिए मुझे अतिरंजनात्मक लगता है । – spender

+2

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

1

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

class DateTime { 

    public static function getNow() { 
     return new self(); 
    } 

    public function __construct() { 
     $this->setDateTime('now'); 
    } 

    public function setDateTime($value) { 
     #... 
    } 

} 

लेकिन इसके अलावा, पहले से ही builtin DateTime class in PHP है।

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