ope*_*sas 2 inheritance scala playframework-2.0 playframework-2.1
在Play 2.1应用程序中,我有以下代码(它只是一个请求包装器,它可以删除任何尾部斜杠):
class NormalizedRequest(request: RequestHeader) extends RequestHeader {
val headers = request.headers
val id = request.id
val method = request.method
val queryString = request.queryString
val remoteAddress = request.remoteAddress
val tags = request.tags
val version = request.version
// strip first part of path and uri if it matches http.path config
val path = if (request.path == "/") "/" else request.path.stripSuffix("/")
val uri = path + {
if(request.rawQueryString == "") ""
else "?" + request.rawQueryString
}
}
object NormalizedRequest {
def apply(request: RequestHeader) = new NormalizedRequest(request)
}
Run Code Online (Sandbox Code Playgroud)
这种代码很常见,你只需将一个对象包装在另一个中
我想知道是否有更简单的方法来实现它,理想情况下它会像(伪代码灵感来自案例类):
object NormalizedRequest {
def apply(request: RequestHeader) = {
val path = if (request.path == "/") "/" else request.path.stripSuffix("/")
val uri = path + {
if(request.rawQueryString == "") ""
else "?" + request.rawQueryString
}
request.copy(path = path, uri = uri)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,那么你需要在scala中提供更简洁的Decorator模式版本.你仍然需要你的"包装器"与你的内部类相同的类型(通过扩展它或一个公共的基础/特征),以便能够将它传递给一些期望接收内部类的实例的函数(或共同的基础/特征).
您在伪代码中编写的内容实际上几乎是合法的scala,您只需更改apply
in 的定义NormalizedRequest
即可返回扩展RequestHeader的匿名类.
即代替
class NormalizedRequest(request: RequestHeader) extends RequestHeader {
//.... "decorated" logic here
}
object NormalizedRequest {
def apply(request: RequestHeader) = new NormalizedRequest(request)
}
Run Code Online (Sandbox Code Playgroud)
你将会拥有
object NormalizedRequest {
def apply(request: RequestHeader) = new RequestHeader {
// ...
// instead of having a separate NormalizedRequest class
// define its behaviour here in anonymous form
}
}
Run Code Online (Sandbox Code Playgroud)
一个简化的例子:
// our inner class and companion object
// (a simplified version of your RequestHeader)
class Inner() {def test="hello"}; object Inner {
def apply() = new Inner()
}
// our wrapper
object Outer {
def apply(inner: Inner) = new Inner {
override def test=inner.test + "!"
}
}
Run Code Online (Sandbox Code Playgroud)
然而,虽然它可以节省你几次击键,但我真的认为你会失去可读性.