2

在 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)
}

这种代码很常见,你只需将一个对象包装在另一个对象中

我想知道是否有更简单的方法来完成它,理想情况下它会像(受案例类启发的伪代码):

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)
  }
}
4

1 回答 1

5

如果我理解正确,您要求在 scala 中提供更简洁的装饰器模式版本。您仍然需要您的“包装器”与您的内部类的类型相同(通过扩展它或公共基础/特征),以便能够将其传递给期望接收内部类实例的某个函数(或共同的基础/特征)。

您在伪代码中编写的内容实际上几乎是合法的 scala,您只需更改 in 的定义applyNormalizedRequest返回扩展 RequestHeader 的匿名类。

即代替

class NormalizedRequest(request: RequestHeader) extends RequestHeader {
    //.... "decorated" logic here
}
object NormalizedRequest {
  def apply(request: RequestHeader) = new NormalizedRequest(request)
}

你将会拥有

object NormalizedRequest {
  def apply(request: RequestHeader) = new RequestHeader {
    // ...
    // instead of having a separate NormalizedRequest class
    // define its behaviour here in anonymous form    
    }
}

一个简化的例子:

// 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 + "!"
    }   
}

然而,虽然它为你节省了几次击键,但我真的认为你会失去可读性。

于 2012-11-20T13:57:07.667 回答