2012-09-05 12 views
8

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

abstract class Post(val id: Int, val name: String, ...) 
case class TextPost(val id: Int, val name: String, ..., val text: String) extends Post(id, name, ...) 
case class PhotoPost(val id: Int, val name: String, ..., val url: String) extends Post(id, name, ...) 

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

उत्तर

8

सबसे पहले, val केस-क्लास कन्स्ट्रक्टर में संशोधक अनावश्यक हैं, स्कैला कंपाइलर उन्हें पहले से ही "मुफ्त में" देगा (यह केस-क्लास की विशेषताओं में से एक है)। आप वास्तव में है कि संकलन करने की कोशिश की, तो आप उस एक त्रुटि अघोषित अधिभावी के कारण होती है देखेंगे:

abstract class Post(val id: Int, val name: String) 
case class TextPost(id: Int, name: String) extends Post(id, name) 
case class PhotoPost(id: Int, name: String) extends Post(id, name) 

<console>:10: error: overriding value id in class Post of type Int; 
value id needs `override' modifier 
      case class PhotoPost(id: Int, name: String) extends Post(id, name) 
           ^

मैं व्यक्तिगत रूप से संभव के रूप में छोटे रूप में निर्माता तर्क के साथ सार वर्गों का उपयोग करने की सलाह देते हैं। स्कैला में ऐसे लक्षण हैं जो यहां बेहतर काम करते हैं। कन्स्ट्रक्टर तर्कों के बजाय, आप खेतों को घोषित करते हैं (संक्षेप में); तो मामले कक्षाएं वजह से उन्हें अपने तर्क स्वचालित रूप से vals बनाने के लिए में लात और, आप कर चुके हैं:

trait Post { def id: Int; def name: String } 
case class TextPost(id: Int, name: String, text: String) extends Post 
case class PhotoPost(id: Int, name: String, url: String) extends Post 

इसके अलावा, अगर आप trait Post को sealed जोड़ने के लिए, आप सुरक्षित रूप से गलती से बिना पैटर्न मिलान में Post के उपप्रकार का उपयोग कर सकते गायब मामले

+0

उत्तर के लिए धन्यवाद! बॉयलर-प्लेट कोड के संदर्भ में, यह विधि मूल रूप से व्युत्पन्न कक्षाओं में प्रत्येक पैरामीटर को वैल के रूप में घोषित करने से बचाती है, लेकिन मुझे अभी भी प्रत्येक घोषणा में सभी पैरामीटर दोहराना होगा, है ना? मैं इस पर जोर दे रहा हूं, क्योंकि मेरे पास 8 सबक्लास और 15 साझा फ़ील्ड हैं, और ऐसा लगता है कि यह इतना बड़ा डीआरवाई मामला है। लेकिन मैं आपके जवाब से समझता हूं कि इसके चारों ओर कोई रास्ता नहीं है, है ना? – orrsella

+1

एकमात्र अन्य विकल्प सामान्य इंटरफ़ेस ('पोस्ट') को लागू नहीं करना है। इसका मतलब है कि आपको इसे शामिल करने के लिए _compose_ की आवश्यकता है, लेकिन मुझे नहीं पता कि यह वही है जो आप चाहते हैं: 'केस क्लास पोस्ट (आईडी: Int, name: स्ट्रिंग); केस क्लास टेक्स्टपोस्ट (पोस्ट: पोस्ट, टेक्स्ट: स्ट्रिंग) '। –

+5

मुझे नहीं लगता कि यह जवाब पर्याप्त है क्योंकि यह बॉयलर प्लेट प्रश्न का उत्तर नहीं देता है ... –

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