2012-11-20 31 views
2

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

这种代码是很常见的,你只是包装内的对象的另一个

我在想,如果有到acomplish它更简单的方法,理想情况下是类似的信息(灵感案例类的伪代码):

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) 
    } 
} 
+0

在这种情况下,我会使用隐式转换为结构类型而不是实际的包装类型。 – mmmbell

回答

5

如果我理解正确,那么您在scala中要求更简洁的Decorator模式版本。你仍然需要你的“包装器”与你的内部类(通过扩展它或者一个通用的基础/特质)是相同的类型,以便能够将它传递给一些希望接收内部类的实例的函数或共同基地/特征)。

你在你的伪代码中写的实际上几乎是合法的scala,你只需要改变NormalizedRequest中的apply的定义来返回一个扩展RequestHeader的匿名类。

I.e.而不是

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

然而,尽管它可以节省你敲击几下键盘,我真的觉得你会在可读性丧失。

相关问题