9
私は、ケーキパターンの変形を実装したいが、暗黙の機能をクラス(Spark DataFrame)に追加するというシナリオがある。だから、暗黙的な機能を持つケーキパターンの実装
、基本的に、私は次のようなコードを実行できるようにしたい:
trait Transformer {
this: ColumnAdder =>
def transform(input: DataFrame): DataFrame = {
input.addColumn("newCol")
}
}
val input = sqlContext.range(0, 5)
val transformer = new Transformer with StringColumnAdder
val output = transformer.transform(input)
output.show
そして、次のような結果を見つける:
+---+------+
| id|newCol|
+---+------+
| 0|newCol|
| 1|newCol|
| 2|newCol|
| 3|newCol|
| 4|newCol|
+---+------+
私の最初の考えはしました基本特性でのみ暗黙のクラスを定義する:
trait ColumnAdder {
protected def _addColumn(df: DataFrame, colName: String): DataFrame
implicit class ColumnAdderRichDataFrame(df: DataFrame) {
def addColumn(colName: String): DataFrame = _addColumn(df, colName)
}
}
trait StringColumnAdder extends ColumnAdder {
protected def _addColumn(df: DataFrame, colName: String): DataFrame = {
df.withColumn(colName, lit(colName))
}
}
とそれはで動作しますが、このアプローチでは完全に満足していませんでした。なぜなら、関数シグネチャの重複のためです。
trait ColumnAdder {
protected implicit def columnAdderImplicits(df: DataFrame): ColumnAdderDataFrame
abstract class ColumnAdderDataFrame(df: DataFrame) {
def addColumn(colName: String): DataFrame
}
}
trait StringColumnAdder extends ColumnAdder {
protected implicit def columnAdderImplicits(df: DataFrame): ColumnAdderDataFrame = new StringColumnAdderDataFrame(df)
class StringColumnAdderDataFrame(df: DataFrame) extends ColumnAdderDataFrame(df) {
def addColumn(colName: String): DataFrame = {
df.withColumn(colName, lit(colName))
}
}
}
(余分な形質のモジュールを含む完全な再現性のあるコードは、here見つけることができます)
だから、私がお聞きしたかった:だから私は(?非推奨)implicit def
戦略を使用して、別のアプローチを考えましたこのアプローチは最高ですが、私が望むものを達成するためのより良い方法があるかもしれません。