2012-01-10 12 views
17

कंक्रीट कक्षाओं के विभिन्न गुणों के अनुसार, मैं गुणों से डोमेन ऑब्जेक्ट्स को इकट्ठा करने में सक्षम होना चाहता हूं। जब मेरी वस्तुएं उत्परिवर्तनीय होती हैं, तो यह बहुत सरल है। उदाहरण के लिए:एक अपरिवर्तनीय श्रेणी पदानुक्रम में पॉलीमोर्फिक अपडेट

trait HasHitPoints { var hitPoints: Int = 100 } 
trait HasBearing { var bearing: Double = 0 } 

class Ship extends HasHitPoints with HasBearing 
class Base extends HasHitPoints 

val entities = new Ship :: new Base :: Nil 
entities.collect { case h: HasHitPoints => h.hitPoints += 10 } 

विशेष रूप से, मैं polymorphically पढ़ने के लिए या ठोस प्रकार जानने के बिना किसी भी HasHitPoints उदाहरण अद्यतन कर सकते हैं।

अपरिवर्तनीय वस्तुओं के साथ इसे लागू करने का सबसे अच्छा तरीका क्या है? अगर मैं सिर्फ गुण पढ़ने के लिए खुश हूँ, तो मैं कुछ ऐसा कर सकता है:

trait HasHitPoints { val hitPoints: Int } 
trait HasBearing { val bearing: Double } 

case class Ship(hitPoints: Int, bearing: Double) extends HasHitPoints with HasBearing 
case class Base(hitPoints: Int) extends HasHitPoints 

val things = Ship(50, 0) :: Base(100) :: Nil 

val totalHitPoints = things.collect { case h: HasHitPoints => h.hitPoints }.sum 

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

उत्तर

1

आपके पास कुछ जोड़ने के साथ कुछ भाग्य हो सकता है अपने लक्षणों के लिए हिट पॉइंट (अंक: Int) विधि के साथ अमूर्त def, जो एक अलग संपत्ति मूल्य के साथ कंटेनर ऑब्जेक्ट की एक प्रति देता है। कुछ इस तरह के उपयोग को कम कर देता:

val damagedActors = actors map { actor => actor.withHitPoints(actor.hitPoints - 10) } 

लेकिन अन्यथा ठोस वर्ग प्रति संपत्ति प्रति एक अतिरिक्त विधि की आवश्यकता होगी, तो मुझे यकीन है कि यह वास्तव में आपकी समस्या नहीं सुलझती नहीं हूँ। यह स्काला जैसी स्थिर भाषा के लिए सही नहीं लगता है (न ही मैं इस विशेष उपयोग-मामले के लिए अपरिवर्तनीयता से परेशान होगा); यहां एक अपरिवर्तनीय समाधान गतिशील भाषा के लिए एक बेहतर उम्मीदवार हो सकता है।

+0

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

+0

मैं तर्क नहीं दूंगा कि यह कुछ ऐसा है जो स्कैला अच्छी तरह से संभाल नहीं पाता है, लेकिन मेरे अनुभव में यह एक परिदृश्य है जो अक्सर फसल नहीं करता है - बशर्ते कि आप मॉडलिंग के इस समय मर चुके हों। –

+2

संभवतया, हालांकि मुझे लगता है कि सैपीर-व्हाफॉर्फ़ चीज़ किस डिग्री की है: परिस्थितियों में एक भाषा अच्छी तरह से संभाल नहीं सकती है जो परिदृश्य नहीं बनती है ... –

1

आप एम कंक्रीट कक्षाओं में एन अद्यतन विधियों से बचने की उम्मीद कर रहे हैं। हालांकि दर्दनाक मुझे लगता है कि यह संभव नहीं है। आपको प्रतिलिपि विधि या कम से कम प्रत्येक कंक्रीट वर्ग के निर्माता की पहुंच की आवश्यकता होगी। उनमें से कोई भी सारणित नहीं किया जा सकता है क्योंकि इसमें भी चर्चा की गई है: Case class copy() method abstraction तो अंत में आप हमेशा एन एक्स एम 'बॉयलरप्लेट' कोड के साथ समाप्त हो जाएंगे।

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