2011-11-27 102 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中。只要可能,只需使用,即名爲的構造函數參數和默認值。如果有太多爭論,那麼重新考慮你的設計。我敢打賭,有很多機會將它們以某種方式分組到適當的數據結構中,從而減少構造函數參數的數量。

相關問題