2017-02-11 25 views
2

У меня есть базовая чертаКак сбрасывать шаблон для строительства класса scala?

trait MyClass{ 

    def items: List[MyClass] 

    def op(c: MyClass): MyClass 
} 

и несколько конкретных подтипов.

Я хочу, чтобы каждый из подтипов реализовал этот метод op из родительского признака, но единственная разница в реализации - это класс, который они строят.

class Class1(override val items: List[MyClass]) extends MyClass = { 
    def op(c: MyClass): MyClass = new Class1(items.map{_.op(c)}) 

    //other stuff 
} 

class Class2(override val items: List[MyClass]) extends MyClass = { 
    def op(c: MyClass): MyClass = new Class2(items.map{_.op(c)}) 

    //other stuff 
} 

class Class3(override val items: List[MyClass]) extends MyClass = { 
    def op(c: MyClass): MyClass = new Class3(items.map{_.op(c)}) 

    //other stuff 
} 

Это кажется довольно избыточным, и я чувствую, что должен быть лучший способ. Я посмотрел на некоторые подобные ситуации, и кажется, что люди прибегают к отражению во время выполнения, чтобы найти правильный конструктор.

Есть ли способ автоматически сгенерировать этот шаблон во время компиляции?

Спасибо.

ответ

2

Используйте шаблон проектирования метод шаблона: https://www.tutorialspoint.com/design_pattern/template_pattern.htm

В вашей черты, реализовать оп() с вызовом защищенного метода.

def op(c: MyClass): MyClass = createObject(items.map{_.op(c)}) 
protected def createObject(inItems: List[MyClass]): MyClass 

Затем в подтипов, осуществлять CreateObject(), так что она возвращает правильный объект:

override def createObject(inItems: List[MyClass]) = new Class1(inItems) 

Замена Class1 при необходимости, конечно.

Это не полностью автогенерировано, но есть меньше дублирования.