当你在编译时知道配置时它们很好,但是当你需要根据某些运行时条件构建一个对象时,它看起来很奇怪。
val req = Request()
val secureReq = if (needSecurity) req.withSecurity else req
val throttledReq = if (needThrottling) secureReq.withThrottling else secureReq
val pooledReq = if (needPooling) throttledReq.withPooling else throttledReq
// etc etc ad infinitum
也许在Scala中编写这种代码有更好,更简洁的方法吗?
答案 0 :(得分:3)
Scala暗示救援。
object PimpedBuilders {
implicit class Pimped[T](val builder: T) extends AnyVal {
def unless(what: Boolean)(then: T => T): T =
if(what) builder else then(builder)
}
}
import PimpedBuilders._
req
.unless(!needSecurity){ _.withSecurity}
.unless(!needThrottling} { _.withThrottling }
.unless(!needPooling) { _.wothPooling }
等
答案 1 :(得分:1)
这个解决方案有点复杂,但应该避免重复自己。
请注意,我无法检查REPL上的代码,但它应该会给你一个想法。
/************************************************
* This part is used once
************************************************/
//We define a request-transforming type
type Configuration = Request => Request
/* now we prepare configuration selectively based on a flag
* the function is curried to store different configurations
* once, leaving the flag to be defined only as we actually
* prepare the request.
* Note that a false flag will give back the identity function
* from Predef that leaves the argument untouched
*/
def configuring(conf: Configuration)(flag: boolean) =
if (flag) conf else identity
//The available configuration types, wrapping the "fluent" calls
val secured_?: Boolean => Configuration = configuring(_.withSecurity)
val throttled_? = configuring(_.withThrottling)
val pooled_? = configuring(_.withPooling)
/************************************************
* This part is used each time we need
* to configure a request
************************************************/
val req = Request()
/* prepare a sequence of configurations
* and compose them sequentially
*/
def configurations: Configuration = Seq(
secured_?(needSecurity),
throttled_?(needThrottling),
pooled_?(needPooling)
).reduce(_.compose(_))
/* apply the combined configuring
* function to the new request
*/
val configured = configurations(req)