What is the Scala equivalent to a Java builder pattern?

前端 未结 5 585
遇见更好的自我
遇见更好的自我 2020-12-23 13:31

In the work that I do on a day to day in Java, I use builders quite a lot for fluent interfaces, e.g.: new PizzaBuilder(Size.Large).onTopOf(Base.Cheesy).with(Ingredien

5条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-23 13:49

    Case classes solve the problem as shown in previous answers, but the resulting api is difficult to use from java when You have scala collections in your objects. To provide a fluent api to java users try this:

    case class SEEConfiguration(parameters : Set[Parameter],
                                   plugins : Set[PlugIn])
    
    case class Parameter(name: String, value:String)
    case class PlugIn(id: String)
    
    trait SEEConfigurationGrammar {
    
      def withParameter(name: String, value:String) : SEEConfigurationGrammar
    
      def withParameter(toAdd : Parameter) : SEEConfigurationGrammar
    
      def withPlugin(toAdd : PlugIn) : SEEConfigurationGrammar
    
      def build : SEEConfiguration
    
    }
    
    object SEEConfigurationBuilder {
      def empty : SEEConfigurationGrammar = SEEConfigurationBuilder(Set.empty,Set.empty)
    }
    
    
    case class SEEConfigurationBuilder(
                                   parameters : Set[Parameter],
                                   plugins : Set[PlugIn]
                                   ) extends SEEConfigurationGrammar {
      val config : SEEConfiguration = SEEConfiguration(parameters,plugins)
    
      def withParameter(name: String, value:String) = withParameter(Parameter(name,value))
    
      def withParameter(toAdd : Parameter) = new SEEConfigurationBuilder(parameters + toAdd, plugins)
    
      def withPlugin(toAdd : PlugIn) = new SEEConfigurationBuilder(parameters , plugins + toAdd)
    
      def build = config
    
    }
    

    Then in java code the api is really easy to use

    SEEConfigurationGrammar builder = SEEConfigurationBuilder.empty();
    SEEConfiguration configuration = builder
        .withParameter(new Parameter("name","value"))
        .withParameter("directGivenName","Value")
        .withPlugin(new PlugIn("pluginid"))
        .build();
    

提交回复
热议问题