2013-05-13 6 views
6

के साथ नाम टकराव से बचें मैं वर्तमान में वर्तमान में केक पैटर्न का उपयोग कर रहा हूं ताकि कुछ ऑप्टिमाइज़ेशन एल्गोरिदम लागू हो सकें। मैं अक्सर नाम टकराव की समस्याओं को मारा। उदाहरण के लिए:केक पैटर्न

trait Add[T] { this: Foo[T] => 
    def constant: T 
    def plus(t1: T, t2: T): T 
    def add(t: T) = plus(t, constant) 
} 

trait Mul[T] { this: Bar[T] => 
    def constant: T 
    def times(t1: T, t2: T): T 
    def mul(t: T) = times(t, constant) 
} 

trait Operations[T] { this: Add[T] with Mul[T] => 
    def neg(t: T): T 
} 

यहाँ, constant दोनों Add और Mul लक्षण में परिभाषित किया गया है, लेकिन उनके मान भिन्न हो सकता है। मैं विशेषता नाम के साथ नाम उपसर्ग कर सकता हूं लेकिन मुझे यह बदसूरत और भंगुर लगता है (def mulConstant: T)। क्या ऐसा करने का एक बेहतर तरीका है?

उत्तर

7

मेरे सर्वोत्तम ज्ञान के लिए, परंपरागत केक पैटर्न में आमतौर पर समूह संचालन के लिए विशेषता घोंसले की 1 परत शामिल होती है। फिर, बाहरी परत वास्तविक "सेवा" (यहां: जोड़ें, Mul, संचालन) को परिभाषित किए बिना घोषित करती है।

trait AddComponent[T] { this: FooComponent[T] => 
    def addition: Add 

    trait Add { 
    def constant: T 
    def plus(t1: T, t2: T): T 
    def add(t: T) = plus(t, constant) 
    } 
} 

trait MulComponent[T] { this: BarComponent[T] => 
    def multiplication: Mul 

    trait Mul { 
    def constant: T 
    def times(t1: T, t2: T): T 
    def mul(t: T) = times(t, constant) 
    } 
} 

trait OperationsComponent[T] { this: Add[T] with Mul[T] => 
    def operations: Operations 

    trait Operations { 
    def neg(t: T): T 
    } 
} 

तब, जब "... घटक" लक्षण एक साथ मिश्रण, निर्भरता तार कर रहे हैं:

trait IntOperations extends Operation[Int] { 
    class IntAdd extends Add { ... } 
    class IntMul extends Mul { ... } 
} 

class MyFooBar extends FooComponent[Int] with BarComponent[Int] with IntOperations { 
    lazy val addition = new IntAdd 
    lazy val multiplication = new IntMul 
    lazy val foo = ... 
    lazy val bar = ... 
} 

यह अपने विशेष नेमस्पेसिंग समस्या लेकिन ("सेवा" परिभाषा के) नाम संघर्ष को हल करती है रहते हैं पारंपरिक केक पैटर्न की एक समस्या। डैनियल स्पिवाक द्वारा blog post का प्रदर्शन किया गया है कि यह सामान्य रूप से हल किया जा सकता है लेकिन समाधान अपने स्वयं के (विशाल) ट्रेडऑफ के सेट (this talk देखें) के साथ आता है।

आशा है कि थोड़ा सा मदद मिलेगी।

पीएस टाइप पैरामीटर के बजाय यहां

+0

आपके उत्तर के लिए धन्यवाद, यह वास्तव में मेरी समस्या का समाधान करता है। अपने पीएस के संबंध में, यदि मैं प्रत्येक विशेषता में सार प्रकार 'टी' परिभाषित करता हूं (क्योंकि इसे "घटक" स्तर पर परिभाषित किया जाना चाहिए) तो मेरे पास नाम प्रकार के संघर्ष भी होंगे। क्या मै गलत हु ? – paradigmatic

+0

इस विशेष मामले में, 'टी' का अर्थ सभी लक्षणों में एक ही "चीज़" है, इसलिए वे संघर्ष नहीं करेंगे। यहां तक ​​कि यदि प्रत्येक विशेषता एक अलग प्रकार के साथ टी को योगदान देती है, तो वे संघर्ष नहीं करेंगे, जब वे एक साथ मिश्रित होते हैं तो उनके प्रकार की सीमाएं अलग-अलग लक्षणों से एकत्र की जाती हैं। जब तक वे बाध्य नहीं करते हैं, चीजें ठीक होती हैं (कंपाइलर के लिए)। यह एक बात है कि डैनियल स्पिवाक उस ब्लॉग पोस्ट में दिखाती है। फिर भी, मैं व्यक्तिगत रूप से "घटक" स्तर पर 'टी' की तुलना में एक अधिक वर्णनात्मक नाम पर एक सार प्रकार देता हूं, क्योंकि 2 'टी का मतलब 2 अलग-अलग घटकों में एक ही चीज़ का जरूरी नहीं है। –

+0

ठीक है। लेकिन यहां मुझे यह सुनिश्चित करने की ज़रूरत है कि प्रकार एकजुट होते हैं ('टाइप टी = इंट' हर जगह), इसलिए मुझे निर्भरता व्यक्त करने की आवश्यकता है कि मिश्रित सभी लक्षणों में समान 'टी' है। मैं नहीं देखता कि जेनेरिक प्रकारों को छोड़कर इसे कैसे प्राप्त किया जाए। – paradigmatic

0

यह कहने के लिए थोड़ा अवांछनीय हो सकता है, और यह आपके प्रश्न का सीधा जवाब नहीं है, लेकिन क्या रचनाकारों में निर्भरता इंजेक्शन करना आसान नहीं है? प्रत्येक सहयोगी का अपना नामस्थान होता है इसलिए कभी संघर्ष नहीं होता है। और कक्षा के सार्वजनिक एपीआई के साथ कोई समस्या नहीं है। हालांकि, डीआई और केक पैटर्न को अंतःस्थापित करना मुश्किल है।

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