2011-11-27 51 views
2

我必须根据命令行参数创建类BenchmarkOption的实例。我当然使用pojo风格,但这不是不变的。所以我使用Java风格的Builder模式。这里是我执行的类:有没有更好的选择在Scala中实现Builder模式?

object CommandLineHelper { 
    //TODO: use configuration file ? 
    val MILLI_SEC_SEPERATORS = 0 + "," + Int.MaxValue 
    val SBE_ID = "SBETEST5"; 
    val SBE_PSW = "[email protected]"; 
    val NUM_OF_REQUESTS = 1 
    val NUM_OF_WORKERS = 1 
    val PAUSE_IN_MILlI_SECOND = 1L; 
} 

class BenchmarkOption private { 
    import com.ggd543.mulerestletdemo.{CommandLineHelper => CLH} 
    private var _msSeperators = CommandLineHelper.MILLI_SEC_SEPERATORS 
    def msSeperators = _msSeperators 

    private var _nOfReq = CLH.NUM_OF_REQUESTS 
    def nOfReq = _nOfReq 

    private var _sbeId = CLH.SBE_ID 
    def sbeId = _sbeId 

    private var _sbePsw = CLH.SBE_PSW 
    def sbePsw = _sbePsw 

    private var _pauseInMilliSec = CLH.PAUSE_IN_MILlI_SECOND; 
    def pauseInMillSec = _pauseInMilliSec 

    private var _dataFile = new File("./data.csv") 
    def dataFile = _dataFile 
    // may be too many fields 

} 

object BenchmarkOption { 
    def newBuilder() = new Builder 

    class Builder { 
    private val bmo = new BenchmarkOption 

    def buildBenchmarkOption = bmo; 

    def msSeperators_=(s: String) = bmo._msSeperators = s 
    def msSeperators = bmo._msSeperators 

    def nOfReq_=(n: Int) = bmo._nOfReq = n 
    def nOfReq = bmo._nOfReq 

    def sbeId_=(s: String) = bmo._sbeId = s 
    def sbeId = bmo._sbeId 

    def sbePsw_=(s: String) = bmo._sbePsw = s 
    def sbePsw = bmo._sbePsw 

    def pauseInMilliSec_=(milliSec: Long) = bmo._pauseInMilliSec = milliSec 
    def pauseInMilliSec = bmo._pauseInMilliSec 

    def dataFile_=(file: File) = bmo._dataFile = file 
    def dataFile = bmo._dataFile 

    } 


} 

正如你可以看到代码冗长而且不擅长阅读。我认为有一个替代方案来重写它。任何建议?

回答

0

这个怎么样?

class BenchmarkOption private { 
    protected val instance = new { 
     var msSeperators = CommandLineHelper.MILLI_SEC_SEPERATORS 
     var nOfReq = CLH.NUM_OF_REQUESTS 
     var sbeId = CLH.SBE_ID 
     var sbePsw = CLH.SBE_PSW 
     var pauseInMilliSec = CLH.PAUSE_IN_MILlI_SECOND; 
    var dataFile = new File("./data.csv") 
    def buildInstance() = BenchmarkOption.this; 
    } 

    def msSeperators = instance.msSeperators 

    def nOfReq = instance.nOfReq 

    def sbeId = instance.sbeId 

    def sbePsw = instance.sbePsw 

    def pauseInMilliSec = instance.pauseInMilliSec 

    def dataFile = instance.dataFile 

} 

object BenchmarkOption { 
    def newBuilder() = new BenchmarkOption{}.instance 
} 
1

我不明白你为什么'只是使用构造函数参数 - 所有的参数从一开始就不知道吗?

+0

因为其中有太多的参数,可能从一开始就不知道。 :-) –

+0

关于:如agilesteel指出,可能表明一些遗漏abstgractions,这可能归类在一起。关于从一开始就不知道它们:这是使用构建器的一个很好的理由。 –

3

Builder模式内置于Scala中。只要可能,只需使用,即名为的构造函数参数和默认值。如果有太多争论,那么重新考虑你的设计。我敢打赌,有很多机会将它们以某种方式分组到适当的数据结构中,从而减少构造函数参数的数量。

相关问题