Каковы преимущества подхода торта при расширении старомодных признаков?

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

С помощью расширения

trait X {
  def foo()
}

trait Y extends X {
  def bar()
}

class Z extends Y {
  def foo() = ()
  def bar() = ()
}

И через Cake

trait N {
  def foo()
}

trait M {
  this: N =>
  def bar()
}

class U extends M with N {
  def bar() = ()
  def foo() = ()
}

Каковы преимущества метода торта? Они оба одинаковы для меня. Может я и ошибаюсь, но принципиальной разницы не вижу.


person Finkelson    schedule 13.12.2015    source источник


Ответы (1)


Если я хочу обогатить функциональность X, первый подход:

// I am X
// I give you everything X provides
trait Y extends X {
  def bar()
}

Если я хочу использовать функциональность N, я бы использовал второй подход:

// I am an extension of N
// I require you to be N
trait M { this: N =>
  def bar()
}

Основное преимущество «тортового подхода» по сравнению со «старой модой» заключается в том, что он не устанавливает ограничение иерархии заранее и позволяет избежать (в конечном счете) проблемы алмаза с помощью «линеаризации признаков».

Черты, формирующие class U, реализованные в вашем примере, разрешаются справа налево. Наличие разумного порядка разрешения методов (MRO) дает нам свободу смешивать любые черты «наращиваемым образом».

person Filippo Vitale    schedule 13.12.2015