在 Scala 中是否有更好的替代方案来实现构建器模式?

发布于 2024-12-18 00:23:21 字数 1739 浏览 1 评论 0原文

我必须根据命令行参数创建 BenchmarkOption 类的实例。我当然使用pojo风格,但这并不是一成不变的。所以我使用Java风格的Builder Pattern。这是我实现的类:

object CommandLineHelper {
  //TODO: use configuration file ?
  val MILLI_SEC_SEPERATORS = 0 + "," + Int.MaxValue
  val SBE_ID = "SBETEST5";
  val SBE_PSW = "GZ@API53";
  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

  }


}

正如你所看到的,代码很长并且不利于阅读。我认为有一个替代方案可以重写它。有什么建议吗?

I have to create an instance of class BenchmarkOption based on the command line arguments. I certainly use pojo style, but this is not immutable. So I use Builder Pattern of Java style. Here is the class I implement :

object CommandLineHelper {
  //TODO: use configuration file ?
  val MILLI_SEC_SEPERATORS = 0 + "," + Int.MaxValue
  val SBE_ID = "SBETEST5";
  val SBE_PSW = "GZ@API53";
  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

  }


}

As you can see that the code is lengthy and not good at reading. I think there is an alternative to rewrite it . Any suggestion ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海蓝天 2024-12-25 00:23:21

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

The Builder Pattern is built into Scala. Just use named constructor arguments and default values whenever possible. If there are too many arguments, then rethink your design. I bet there are plenty opportunities to group them somehow into proper data structures, thus reducing the number of constructor arguments.

许仙没带伞 2024-12-25 00:23:21

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

I don't see why you can' just use constructor arguments - are all parameters not known from the start?

梦醒时光 2024-12-25 00:23:21

这个怎么样?

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
}

How about this ?

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文