2012-03-08 12 views
18

मैं अभी भी स्कैला के केक पैटर्न सीखने की कोशिश कर रहा हूं। ऐसा लगता है कि यह आपको "घटक" की अपनी कॉन्फ़िगरेशन को केंद्रीकृत करने के साथ-साथ उन घटकों के लिए डिफ़ॉल्ट कार्यान्वयन प्रदान करने की क्षमता प्रदान करता है (जो निश्चित रूप से ओवरड्रेबल हैं)।स्कैला केक पैटर्न हार्डकोडेड निर्भरता को प्रोत्साहित करते हैं?

हालांकि, निर्भरता का वर्णन करने के लिए स्वयं प्रकार के लक्षणों का उपयोग क्षेत्र-संबंधी चिंताओं को मिश्रण करने लगता है। घटक का उद्देश्य (मुझे लगता है) उस घटक के लिए विभिन्न कार्यान्वयन को दूर करना है। लेकिन घटक में वर्णित निर्भरता-सूची स्वयं एक कार्यान्वयन चिंता है।

case class Widget(id: Int, name:String) 

trait DatabaseComponent { 
    def database: (Int => Widget) = new DefaultDatabase() 

    class DefaultDatabase extends (Int => Widget) { 
    // silly impl 
    def apply(x: Int) = new Person(x, "Bob") 
    } 
} 

trait RegistryComponent { 
    this: DatabaseComponent => // registry depends on the database 

    def registry: (List[Int] => List[Widget]) = new DefaultRegistry() 

    class DefaultRegistry extends (List[Int] => List[Widget]) { 
    def apply(xs: List[Int]) = xs.map(database(_)) 
    } 
} 

trait AlgorithmComponent { 
    this: RegistryComponent => // algorithm depends on the registry 

    def algorithm: (() => List[Widget]) = new DefaultAlgorithm() 

    class DefaultAlgorithm extends (() => List[Widget]) { 
    // look up employee id's somehow, then feed them 
    // to the registry for lookup 
    def apply: List[Widget] = registry(List(1,2,3)) 
    } 
} 
:

उदाहरण के लिए, मान लीजिए कि मैं एक डेटाबेस विगेट्स से भरा, एक रजिस्ट्री कि मुझे विजेट के विशिष्ट प्रकार को देखने के लिए अनुमति देता है, और कलन विधि किसी प्रकार का विजेट कार्रवाई करने के लिए रजिस्ट्री का उपयोग करता है डालते हैं

और अब आप कुछ केंद्रीय config में एक साथ डाल दिया कर सकते हैं:

: आसानी से अपने mixin बदलकर

object Main { 
    def main(args: Array[String]) { 
    val algorithm = new AlgorithmComponent() with RegistryComponent with DatabaseComponent 

    val widgets = println("results: " + algorithm.processor().mkString(", ")) 
    } 
} 

मैं एक अलग डेटाबेस के लिए बदलना चाहते हैं, मैं इसे इंजेक्षन कर सकते हैं


लेकिन ... अगर मैं एक अलग रजिस्ट्री घटक में मिश्रण करना चाहता हूं तो डेटाबेस डेटाबेस का उपयोग नहीं करता है?

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

क्या मुझे कुछ याद आ रही है? जिस क्षण मैं अपने किसी भी घटक में एक स्व-प्रकार का उपयोग करता हूं, मैं यह घोषणा कर रहा हूं कि सभी संभावित कार्यान्वयनों को उन समान निर्भरताओं का उपयोग करना चाहिए।

क्या कोई और इस मुद्दे पर चलता है? इसे हल करने के केक जैसा तरीका क्या है?

धन्यवाद!

+0

डेव की तरह कहते हैं, आप इंप्रेशन को कम करने के लिए इंटरफेस खो रहे हैं। यदि आप केक पैटर्न के बारे में क्या सोच रहे हैं, तो ईजेबी और स्प्रिंग देखें: एक कंटेनर जो लेनदेन, सुरक्षा और संसाधन कॉन्फ़िगरेशन जैसी चिंताओं से अवगत है। केक पैटर्न उस पते को संबोधित नहीं करता है, और जैसे, Google Guice की तरह, केवल हल्का वजन है। –

उत्तर

17

केक पैटर्न के साथ, कम से कम example I always go to द्वारा, आपको घटक की इंटरफ़ेस परिभाषा को इसके डिफ़ॉल्ट कार्यान्वयन से अलग करना चाहिए। यह कार्यान्वयन की निर्भरताओं से इंटरफ़ेस की निर्भरताओं को स्पष्ट रूप से अलग करता है।

trait RegistryComponent { 
    // no dependencies 
    def registry: (List[Int] => List[Widget]) 
} 

trait DefaultRegistryComponent extends RegistryComponent { 
    this: DatabaseComponent => // default registry depends on the database 

    def registry: (List[Int] => List[Widget]) = new DefaultRegistry() 

    class DefaultRegistry extends (List[Int] => List[Widget]) { 
    def apply(xs: List[Int]) = xs.map(database(_)) 
    } 
} 
+5

सही। स्व-प्रकार किसी अन्य प्रकार की निर्भरता घोषणा की तरह हैं। वे एक ठोस इकाई (खराब) या एक अमूर्त (अच्छा) पर निर्भरता दिखा सकते हैं। एकमात्र चाल यह है कि केक पैटर्न अमूर्त इंटरफेस और कंक्रीट घटकों दोनों को गुणों के रूप में एन्कोड करता है, जो भ्रमित हो सकता है। –

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