Scala - 特征中的模板方法模式

Posted

技术标签:

【中文标题】Scala - 特征中的模板方法模式【英文标题】:Scala - template method pattern in a trait 【发布时间】:2019-07-23 10:54:36 【问题描述】:

我正在 Scala 中实现模板方法模式。这个想法是该方法返回一个Dataset[Metric]

但是当我将enrichedMetrics 转换为DataSet enrichedMetrics.as[Metric] 时,我必须使用implicits 来将记录映射到指定的类型。这意味着将 SparkSession 传递给MetricsProcessor,这对我来说似乎不是最好的解决方案。

我现在看到的解决方案是将spark: SparkSession作为参数传递给模板方法。然后在模板方法中导入 spark.implicits._。

在这种情况下,有没有更合适的方式来实现模板方法模式?

  trait MetricsProcessor  

  // Template method
  def parseMetrics(startDate: Date, endDate: Date, metricId: Long): Dataset[Metric] = 
    val metricsFromSource: DataFrame = queryMetrics(startDate, endDate)
    val enrichedMetrics = enrichMetrics(metricsFromSource, metricId)
    enrichedMetrics.as[Metric] <--- //requires spark.implicits
  

  // abstract method
  def queryMetrics(startDate: Date, endDate: Date): DataFrame

  def enrichMetrics(metricsDf: DataFrame, metricId: Long): DataFrame = 
  /*Default implementation*/
  
 

【问题讨论】:

实际上你不需要spark.implicits._,而只是它带来的一个隐含含义,一个Encoder[Metrics]。您可能只要求将其作为方法的隐式参数。此外,如果Metrics 是一个具体的案例类,您可以使用org.apache.spark.sql.Encoders.product 辅助方法自己创建Encoder(我可能有错别字,但我希望这可以帮助你). @LuisMiguelMejíaSuárez 你能举个例子吗? 如果 Metric 是用户无法指定的类型参数,则 def parseMetrics(...)(implicit encoder: Encoder[Metric]): Dataset[Metric] (其中的点是您的常规参数)。 - 如果 Metric 是一个具体的案例类,则为 MetricProcessor 创建一个伴随对象,并将其放在那里 implicit val metricEncoder: Encoder[Metric] = Encoders.product & 要么放在特征的主体上,要么放在方法添加import MetricProcessor._ - 顺便说一句,我会把这个方法定为最终的。 【参考方案1】:

您在此处缺少您的类型 MetricEncoder,这是 spark 无法隐式找到的,对于 StringInt 等常见类型,spark 具有隐式编码器。

此外,如果源类型和目标类型中的列不同,则不能对数据框执行简单的.as。我会在这里做一些假设。

对于case class 指标

case class Metric( ??? )

parseMetrics 中的行将变为,

选项 1 - 显式传递编码器

enrichedMetrics.map(row => Metric( ??? ))(Encoders.product[Metric])

选项 2 - 隐式传递编码器

implicit val enc : Encoder[Metric] = Encoders.product[Metric]
enrichedMetrics.map(row => Metric( ??? ))

请注意,正如其中一个 cmets 所指出的,如果您的 parseMetric 方法始终返回 Dataset[Metric],您可以将隐式编码器添加到特征主体。

希望这会有所帮助。

【讨论】:

以上是关于Scala - 特征中的模板方法模式的主要内容,如果未能解决你的问题,请参考以下文章

Scala面向对象和模式匹配

指纹模式识别算法源码及其测试和应用方法

指纹模式识别算法源码及其测试和应用方法

Scala-Unit5-Scala面对对象与模式匹配

模板方法模式:剖析模板方法在JDKTomcatMybatis等开源框架中的应用

设计模式整理_模板模式