5

मुझे एहसास है कि इस विषय को मृत्यु में शामिल किया गया है लेकिन मैं अभी भी संघर्ष कर रहा हूं और कुछ विशिष्ट सहायता के साथ कर सकता हूं।ढीले रूप से युग्मित पर्यवेक्षक पैटर्न

मेरा उद्देश्य किसी प्रकार के अवलोकन करने योग्य (एक कुत्ता कहने देता है) और किसी प्रकार का श्रोता (मालिक कहने देता है) के बीच एक सरल पर्यवेक्षक पैटर्न को लागू करना है।

आखिरकार मालिक एमवीसी प्रतिमान में 'व्यू' और डॉग ए 'मॉडल' होगा। मैं यहां चीजों को आजमाने और सरल बनाने के लिए कुत्ते और मालिक का उपयोग कर रहा हूं।

मैंने जावा के अंतर्निहित पर्यवेक्षक/पर्यवेक्षण वर्गों का उपयोग करने का प्रयास किया है, लेकिन यह महसूस किया है कि पर्यवेक्षकों को अद्यतन() विधि कितनी खराब है - इसे पीओजेओ प्राप्त होता है और मुझे अद्यतन() विधि में उस POJO को चेक/कास्ट करने की आवश्यकता होगी। मैं अपनी 'अपडेट()' विधि को प्राप्त करने के लिए बहुत कुछ पसंद करूंगा।

http://www.youtube.com/watch?v=qw0zZAte66A

यहाँ मैं कैसे अपने ही पर्यवेक्षक/मनाया कक्षाएं रोल दिखाया गया है:

तो, मैं इस एक जो एक उदाहरण के रूप कुत्ता/स्वामी का उपयोग करता है सहित कुछ ट्यूटोरियल, पीछा किया। छद्म कोड में, क्या मैं अब यह है:

Dog/Model { 

    List listeners; 

    public fireDogHungryEvent() { 

     foreach listener { 
      listener.onDogHungry(this); 
     } 
    } 

    public fireDogPeeEvent() { 

     foreach listener { 
      listener.onDogNeedsToPee(this); 
     } 
    } 

    public getHungerLevel() { return hungerLevel; } 
    public getBladderCapacity() { return bladderCapacity; } 
} 

Owner/View { 

    public onDogHungry(model) { 
     println(model.getHungerLevel()); 
    } 

    public onDogNeedsToPee(model) { 
     println(model.getBladderCapacity()); 
    } 
} 

तो अब के बजाय एक अद्यतन() विधि, मैं तरीकों कि विशिष्ट घटनाओं को संभालने की है। प्रतिभाशाली। मैं वर्तमान में मालिक/दृश्य वर्ग से खुश हूं। यह कुत्ते/मॉडल के तरीकों के बारे में जानता है और यह ठीक है (मुझे लगता है)।

मुझे जो पसंद नहीं है वह यह है कि कुत्ते/मॉडल के मालिक/दृश्य में विधियों के संदर्भ हैं। मैंने अनगिनत बार पढ़े हैं और पूरी तरह से सहमत हैं कि एक मॉडल को अपने विचारों के साथ कसकर नहीं जोड़ा जाना चाहिए जैसा कि यह ऊपर जैसा प्रतीत होता है। मैं कुत्ते/मॉडल में लगभग सभी चीजों को करने के लिए सभी 'आग' विधियों पर भी उत्सुक नहीं हूं; अपने सभी श्रोताओं पर लूपिंग और बस प्रत्येक श्रोता पर एक अलग विधि बुलाओ।

क्या इस संबंध को और अधिक खराब करना संभव है और कुत्ते/मॉडल कॉल विशिष्ट तरीकों से नहीं है? यदि हां, तो मालिक/दृश्य में कुत्ते/मॉडल डेटा प्राप्त करने और उचित तरीके से इसके साथ काम करने का सबसे अच्छा तरीका क्या है?

धन्यवाद

+0

'कुत्ते' के किस तरीके के संदर्भ में संदर्भ हैं? मुझे कोई नहीं दिख रहा है। – SJuan76

+0

एक इंटरफ़ेस का उपयोग करने का सबसे अच्छा तरीका है, जिसे वीडियो ट्यूटोरियल सुझाता है। श्रोता आपके कार्यान्वयन में एक इंटरफ़ेस है? –

+0

SJuan76 - जिन संदर्भों के बारे में मैं बात कर रहा हूं वे श्रोताओं के लिए कॉल हैं। डॉग 'हॉग' में डॉगनहंग्री और श्रोता.ऑडोगनडेड्स टोपी। – whoshotdk

उत्तर

3

आप Observable

public enum EventType { 

    HUNGRY, 
    PEE; 
} 

public interface DogEvent { 

    EventType getType(); 
} 

public interface DogListener { 

    void fireEvent(DogEvent event); 
} 

public class Dog { 

    private final Set<DogListener> listeners = new CopyOnWriteArraySet<DogListener>(); 

    public void register(final DogListener dogListener) { 
     listeners.add(dogListener); 
    } 

    public void unregister(final DogListener dogListener) { 
     listeners.remove(dogListener); 
    } 

    public void firePeeEvent() { 
     fireEvent(new DogEvent() { 
      @Override 
      public EventType getType() { 
       return EventType.PEE; 
      } 
     }); 
    } 

    public void fireHungryEvent() { 
     fireEvent(new DogEvent() { 
      @Override 
      public EventType getType() { 
       return EventType.HUNGRY; 
      } 
     }); 
    } 

    private void fireEvent(final DogEvent dogEvent) { 
     for (final DogListener listener : listeners) { 
      listener.fireEvent(dogEvent); 
     } 
    } 
} 

public class Owner implements DogListener { 

    @Override 
    public void fireEvent(DogEvent event) { 
     switch (event.getType()) { 
      case PEE: 
       System.out.println("Someone take the dog out"); 
       break; 
      case HUNGRY: 
       System.out.println("I can't believe the dog is hungry _again_!"); 
       break; 
     } 
    } 
} 

इस मामले DogOwner यह सिर्फ नाम से जाना जाता है कि Owner एक DogListener है के कार्यान्वयन के बारे में पता नहीं है में दोनों Observer से विशिष्ट कार्यान्वयन के ज्ञान दूर interface और चाहिए।

दूसरी ओर OwnerDog के बारे में नहीं जानता है, यह सिर्फ यह जानता है कि इसमें आने वाली DogEvent है।

+0

मुझे यह स्पष्टता के लिए यह जवाब पसंद है, धन्यवाद Boris। मैं विशेष रूप से * केस स्टेटमेंट की तरह नहीं हूं, जिसकी जांच करने की आवश्यकता है कि किस तरह की घटना हुई, लेकिन मुझे लगता है कि यह जादू से नहीं होता है: डी मैं इसे दो अवलोकन/श्रोताओं के साथ जाने दूंगा और देख सकता हूं कि मैं कैसे चल रहा हूं। मैं इस जवाब को आज किसी बिंदु पर स्वीकार करूंगा यदि मैं इसके साथ कुछ उचित कुशलता से गड़बड़ कर सकता हूं! – whoshotdk

+0

आह मुझे अभी एहसास हुआ कि यह मेरे प्रयासों में पहले की कोशिश की गई एक बेहतर कार्यान्वयन है; सिवाय इसके कि मैं इवेंट ऑब्जेक्ट की बजाय स्ट्रिंग नाम के आधार पर विधियों को आमंत्रित करने के प्रतिबिंब का उपयोग कर रहा था। मुझे लगता है कि यह काम करने जा रहा है: डी – whoshotdk

+0

'एनम' सिर्फ एक सुझाव था - आप बहुरूपता का पूरी तरह से लाभ उठाने के लिए एक आगंतुक पैटर्न का उपयोग कर सकते हैं। –

1

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

आप आसानी से बस बना सकते हैं या आप google guava से एक का उपयोग कर सकते हैं।

यह वास्तव में कमजोर युग्मन बनाने के लिए मुझे सबसे अच्छा तरीका है।

+0

यह शुरुआत में मेरे लिए एक अच्छा विचार प्रतीत होता था लेकिन कुछ पढ़ने के बाद दूसरों ने ध्यान दिया कि यह पैटर्न अनिवार्य रूप से प्रत्येक पर्यवेक्षक/श्रोता को एक बस के बारे में जानने की आवश्यकता है। नए इवेंट प्रकार जोड़ने से उस बस को भी बदलना होगा। देखें: http://stackoverflow.com/questions/3987391/why- लोग-use-message-event-buses-in-their-code। हो सकता है कि ऐसा लगता है कि यह बुरा नहीं है, idk। – whoshotdk

+1

@ user2373021 क्या आपने कुछ ऐसा देखा है [mbassador] (https://github.com/bennidi/mbassador) - यह एनोटेशन आधारित है, इसलिए आपको अपने श्रोताओं को एनोटेट करने की ज़रूरत है और यह उन चीज़ों को कम करेगा जो वे सुनना चाहते हैं विधि पैरामीटर। यह संदेशों को अतुल्यकालिक रूप से भी भेज सकता है ... –

+0

@ user2373021 यह सच है कि आपको बस उसे आवश्यक सभी वर्गों में बस जोड़ने की आवश्यकता है। हालांकि अधिकांश समय आप एक बड़े पैमाने पर अनुप्रयोगों पर निर्भरता इंजेक्शन कंटेनर जोड़ देंगे जो आपके लिए ईवेंट को इंजेक्ट कर सकता है। लेकिन नए इवेंट प्रकारों को जोड़ने से आपकी बस को प्रभावित नहीं होना चाहिए। यदि आपके पास केवल कुछ कक्षाएं हैं तो मैं सरल श्रोता समाधान के लिए भी जाऊंगा लेकिन यदि आपको अधिक संवाद मिलते हैं और एक दूसरे से और अन्य वर्गों (जैसे सर्वर) के साथ कई संवाद होते हैं। मैं इवेंटबस तंत्र को आज़मा दूंगा। – mszalbach

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