Я разрабатываю простой конвейер обработки данных в Scala. В нем участвуют PipelineStage
, которые transform
некоторые StageOutput
превращают в другие StageOutput
. Pipeline
— это оболочка для последовательности PipelineStage
, которая должна иметь общий доступ ко всем их методам transform
.
Однако у меня возникли проблемы, поскольку оба решения, которые я придумал, принципиально не работают... первое основано на абстрактном полиморфном методе, реализуемом неполиморфным способом (не компилируется), а второе полагается на возможность использовать Seq[AbstractTrait]
там, где AbstractTrait
является полиморфным, что опять же бессмысленно для компилятора. Смотрите следующим образом...
Сценарий 1. Сделать метод transform
полиморфным.
abstract trait PipelineStage {
def transform[A <: StageOutput, B <: StageOutput](in: A): B
}
class PipelineStage2 extends PipelineStage {
def transform(in: StageOutput1): StageOutput2
}
class Pipeline {
def stages: Seq[PipelineStage]
}
Здесь у Pipeline
нет проблем с компиляцией, но этапы не будут компилироваться, поскольку сигнатуры их transform
методов, хотя они и «уважают» полиморфизм абстрактной сигнатуры, на самом деле сами по себе не полиморфны, поэтому не совпадают, насколько компилятор обеспокоен.
Сценарий 2. Сделать сам признак PipelineStage
полиморфным.
abstract trait PipelineStage[A <: StageOutput, B <: StageOutput] {
def transform(in: A): B
}
class PipelineStage2 extends PipelineStage[StageOutput1, StageOutput2] {
def transform(in: StageOutput1): StageOutput2
}
class Pipeline {
def stages: Seq[PipelineStage]
}
Это решает проблему для PipelineStage
, у них нет проблем с компиляцией, и их методы преобразования прекрасно работают сами по себе. Однако сейчас они технически не реализуют один и тот же трейт, поэтому Pipeline
не компилируется, так как Seq[PipelineStage]
теперь бессмысленно...
Существует ли установленный шаблон для реализации полиморфных абстрактных методов без полиморфизма или ссылки на последовательность классов, реализующих один и тот же абстрактный полиморфный признак? Я чувствую, что нет, и что я, вероятно, подошел к этому неправильно, но, возможно, где-то в строке я упускаю синтаксический трюк. Спасибо.
PipelineStage1
первого сценарияtransform
. Была опечатка, а не то, что я пытался скомпилировать. Кроме того, у меня есть несколько других методов и атрибутов дляPipelineStage
, поэтому мне нужно использовать трейт. Однако я как-то не задумывался о том, что междуPipelineStage
иPipeline
нет принципиальной разницы. Я могу поместить все методы, которые я хотел, наPipeline
наPipelineStage
и использовать вашу функцию составления. Спасибо! 02.07.2016Pipeline
вместоPipelineStage
. 02.07.2016