2016-12-06 6 views
3

Stringクラスにいくつかのメソッドを追加したいとします。しかし、適用すべき具体的な暗黙的なクラスは実行時に知られている(戦略パターン)。私は暗黙でビットを果たしたが、来るときスカラ暗黙のクラスと継承

def someMethod(strategy: StringExtensions) : String{ 
    val name = "Pawel" 
    return name.doSth() // Here is the tricky line 
} 
... 
String ret = someMethod(new Strategy1()) 

:我々は

trait StringExtensions { 
    def doSth(str: String): String 
} 

class Strategy1 extends StringExtensions { 
    override def doSth(str: String): String = "a" 
} 

class Strategy2 extends StringExtensions { 
    override def doSth(str: String): String = "b" 
} 

を持っていると言うことができます今、私のクライアントコードは次のようになります。

def someMethod(strategy: StringExtensions) : String{ 
    val name = "Pawel" 
    return strategy.doSth(name) 
} 
... 
String ret = someMethod(new Strategy1()) 

が、私のようなコードを持っているしたいと思います継承でこのユースケースに私は適切な解決策、任意の助けを見つけることができないのですか?

答えて

5

私はあなたが実際にこのようなimplicitsを使用すべきかどうかは確信していませんが、DSLでは有効なユースケースかもしれません。

class StringExtensions(str: String, strategy: StringExtensionsStrategy) { 
    def doSth() = strategy.doSth(str) 
} 

trait StringExtensionsStrategy extends (String => StringExtensions) { 
    final def apply(str: String) = new StringExtensions(str, this) 
    def doSth(str: String): String 
} 

class Strategy1 extends StringExtensionsStrategy { 
    override def doSth(str: String) = "a" 
} 

class Strategy2 extends StringExtensionsStrategy { 
    override def doSth(str: String) = "b" 
} 

def someMethod(implicit strategy: StringExtensionsStrategy) = { 
    val name = "Pawel" 
    name.doSth() 
} 

val ret: String = someMethod(new Strategy1()) 

コメント欄で述べたように、別の符号化はこのようになります:

class StringExtensions(str: String, strategy: StringExtensionsStrategy) { 
    def doSth() = strategy.doSth(str) 
} 

trait StringExtensionsStrategy { 
    implicit final def apply(str: String) = new StringExtensions(str, this) 
    def doSth(str: String): String 
} 

class Strategy1 extends StringExtensionsStrategy { 
    override def doSth(str: String) = "a" 
} 

class Strategy2 extends StringExtensionsStrategy { 
    override def doSth(str: String) = "b" 
} 

def someMethod(strategy: StringExtensionsStrategy) = { 
    import strategy._ 
    val name = "Pawel" 
    name.doSth() 
} 

val ret: String = someMethod(new Strategy1()) 
+1

暗黙 'strategy'パラメータは、最初の行のように暗黙のVal S = strategy' 'で置き換えることができますsomeMethod。 – adamwy

+0

'StringExtensionsStrategy'特性に' apply'メソッドを暗黙的に指定すると、 'import strategy._'が呼び出されます。 – adamwy

+0

これを行うこともできますが、暗黙的なvalとimportを追加した後、 'strategy.doSth(name)'と同じように簡単に書くことができます。だからこそ、これはおそらく良いアイデアではないと言いますが、ユースケースがあるかもしれないと思います。仮説的ユースケースでできる限りの定型文を排除したいと思っていました。 –

関連する問題