2013-06-29 7 views
19

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

+2

मुझे मिली दो सबसे प्रासंगिक पोस्टों में शामिल हैं, आंशिक कार्यों की श्रृंखला को दिखाते हुए, कम से कम स्कैला कलाकारों के लिए: http://www.kotancode.com/2011/07/19/traits-multiple- विरासत -और-अभिनेता-इन-स्कैला/... और फिर यह एक, एक रैपर को कॉल करके स्टेकेबल प्राप्त करने के लिए एक पैटर्न दिखा रहा है: http://grokbase.com/t/gg/akka-user/12ckfs8r7g/stackable-actor -ट्रेट्स ... मुझे लगता है कि दोनों की अपनी ताकत है, लेकिन मुझे नहीं पता कि वे संदर्भ का उपयोग कैसे करेंगे। – sdanzig

उत्तर

22

वास्तव में इस तरह के कई तरीकों से आप जा सकते हैं। मैं ओओ से दो सूचीबद्ध करूंगा (जैसा कि @ रैंडल शूलज़ सुझाव दे रहा है) और 1 और कार्यात्मक तरीका है। पहले संभव समाधान के लिए, आप कुछ इस तरह सरल कर सकता है:

case class MessageA(s:String) 
case class MessageB(i:Int) 
case class MessageC(d:Double) 

trait MyActor extends Actor{ 

    def receive = { 
    case a:MessageA => 
     handleMessageA(a) 

    case b:MessageB => 
     handleMessageB(b) 

    case c:MessageC => 
     handleMessageC(c) 
    } 

    def handleMessageA(a:MessageA) 

    def handleMessageB(b:MessageB) = { 
    //do handling here 
    } 

    def handleMessageC(c:MessageC) 
} 

class MyActor1 extends MyActor{ 
    def handleMessageA(a:MessageA) = {} 
    def handleMessageC(c:MessageC) = {} 
} 

class MyActor2 extends MyActor{ 
    def handleMessageA(a:MessageA) = {} 
    def handleMessageC(c:MessageC) = {} 
} 

इस दृष्टिकोण के साथ, आप मूल रूप से एक अमूर्त अभिनेता impl जहां receive समारोह सभी संदेशों को नियंत्रित किया जाता है के लिए परिभाषित किया गया है परिभाषित करते हैं। संदेश def एस पर दिए गए हैं जहां वास्तविक व्यापार तर्क होगा। दो अमूर्त हैं, ठोस वर्गों को हैंडलिंग को परिभाषित करने दें और एक ऐसे मामले के लिए पूरी तरह लागू किया गया है जहां तर्क को अलग करने की आवश्यकता नहीं है।

अब इस दृष्टिकोण रणनीति पैटर्न का उपयोग करने पर एक संस्करण:

trait MessageHandlingStrategy{ 
    def handleMessageA(a:MessageA) 

    def handleMessageB(b:MessageB) = { 
    //do handling here 
    } 

    def handleMessageC(c:MessageC) 
} 

class Strategy1 extends MessageHandlingStrategy{ 
    def handleMessageA(a:MessageA) = {} 
    def handleMessageC(c:MessageC) = {} 
} 

class Strategy2 extends MessageHandlingStrategy{ 
    def handleMessageA(a:MessageA) = {} 
    def handleMessageC(c:MessageC) = {} 
} 

class MyActor(strategy:MessageHandlingStrategy) extends Actor{ 

    def receive = { 
    case a:MessageA => 
     strategy.handleMessageA(a) 

    case b:MessageB => 
     strategy.handleMessageB(b) 

    case c:MessageC => 
     strategy.handleMessageC(c) 
    } 
} 

यहाँ दृष्टिकोण निर्माण के दौरान एक रणनीति वर्ग है कि एक और ग के लिए से निपटने को परिभाषित करता है में पारित करने के लिए है, ख के साथ फिर से एक ही संभाला जा रहा परवाह किए बिना। दोनों दृष्टिकोण बहुत समान हैं और एक ही लक्ष्य को पूरा करते हैं। पिछले दृष्टिकोण आंशिक समारोह श्रृंखलन का उपयोग करता है और ऐसा दिखाई दे सकता:

trait MessageAHandling{ 
    self: Actor => 
    def handleA1:Receive = { 
    case a:MessageA => //handle way 1 
    } 
    def handleA2:Receive = { 
    case a:MessageA => //handle way 2 
    } 
} 

trait MessageBHandling{ 
    self: Actor => 
    def handleB:Receive = { 
    case b:MessageB => //handle b 
    } 
} 

trait MessageCHandling{ 
    self: Actor => 
    def handleC1:Receive = { 
    case c:MessageC => //handle way 1 
    } 
    def handleC2:Receive = { 
    case c:MessageC => //handle way 2 
    } 
} 

class MyActor1 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{ 
    def receive = handleA1 orElse handleB orElse handleC1 
} 

class MyActor2 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{ 
    def receive = handleA2 orElse handleB orElse handleC2 
} 

यहाँ, कुछ लक्षण सेटअप है कि 3 संदेश प्रकारों के संदेश से निपटने व्यवहार को परिभाषित कर रहे हैं। ठोस कलाकार उन लक्षणों में मिश्रण करते हैं और फिर आंशिक फ़ंक्शन चेनिंग का उपयोग कर अपने receive फ़ंक्शन का निर्माण करते समय वे कौन से व्यवहार चाहते हैं।

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

+0

धन्यवाद! लेकिन मुझे यकीन नहीं है कि यह दो मुद्दों में से किसी एक को कम करता है जो मैं लड़ रहा था। तीसरा या दूसरा रास्ता उसी मुद्दे को भुगतना प्रतीत होता है जैसा कि स्कैला अभिनेता के उदाहरण में था .. विशेषता के भीतर कक्षा को हैंडल विधि में मजबूती से जोड़ना। अन्य 2 "getWrapper" उदाहरण के समान हैं, जहां कुछ कॉल प्राप्त होता है जिसे आप ओवरराइड कर सकते हैं। विरासत/रणनीति योजना काम करेगी। संदर्भ पहुंच को रैपर विधि के लिए एक अभिनेता कॉन्टेक्स्ट पैराम के साथ उपचार किया जाता है।मुझे एहसास हुआ, मेरे मामले में एकमात्र संदेश ठीक उसी तरह से संभाले गए हैं जो अज्ञात हैं, इसलिए शायद यह मेरे लिए लायक नहीं है। – sdanzig

+0

मुझे नहीं पता कि मैं बस थक गया था, लेकिन हाँ, निश्चित रूप से इस पर एक बड़ा रहस्य नहीं है, जिन समाधानों के साथ आपने एक अभिनेता कॉन्टेक्स्ट परम के साथ प्रस्ताव दिया है। हालांकि, मुझे खेद नहीं है क्योंकि मुझे यकीन है कि इसे इस तरह से बाहर रखा जा रहा है दूसरों की मदद करेगा :) – sdanzig

5

अभी तक मुझे अपनी सेवाओं की वास्तविक कार्यक्षमता (तथाकथित "व्यावसायिक तर्क") को कम परत में "परंपरागत" और तुल्यकालिक (और कभी-कभी अवरुद्ध) लाइब्रेरी में धक्का देने का अफसोस नहीं है अभिनेताओं की जटिलता इकाई-परीक्षण w/o हो। अभिनेता वर्गों में जो एकमात्र चीज है वह साझा, दीर्घकालिक उत्परिवर्तनीय राज्य है जिस पर पारंपरिक पुस्तकालय कोड कार्य करता है। वह, ज़ाहिर है, और अक्का अभिनेता receive फ़ंक्शन का संदेश-डिकोडिंग और प्रेषण तर्क।

यदि आप ऐसा करते हैं, तो जिस तरह से आप चाहते हैं उसमें तर्क साझा करना तुच्छ है।

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