Второй также известен как Торт .Преимущество заключается в том, что код внутри класса, в котором есть смешанная черта, становится независимым от конкретной реализации методов и типов этой черты.Это позволяет использовать члены черты, не зная, какова их конкретная реализация.
trait Logging {
def log(msg: String)
}
trait App extends Logging {
log("My app started.")
}
Выше черта Logging
является требованием для App
(требования также могут быть выражены с помощью самоподтипов).Затем в какой-то момент в вашем приложении вы можете решить, какой будет реализация, и смешать черту реализации с конкретным классом.
trait ConsoleLogging extends Logging {
def log(msg: String) = println(msg)
}
object MyApp extends App with ConsoleLogging
Это имеет преимущество перед импортом в том смысле, что требования вашегочасть кода не привязана к реализации, определенной оператором import
.Кроме того, он позволяет создавать и распространять API, который можно использовать в другой сборке где-то еще, при условии, что его требования удовлетворяются путем смешивания в конкретной реализации.
Однако есть несколько вещей, которые следует соблюдатьс использованием этого шаблона.
- Все классы, определенные внутри черты, будут иметь ссылку на внешний класс.Это может быть проблемой, связанной с производительностью, или когда вы используете сериализацию (когда внешний класс не сериализуем, или хуже, если это так, но вы не хотите, чтобы он сериализовался).
- Если ваш «модуль» становится действительно большим, у вас будет очень большая черта и очень большой исходный файл, или вам придется распределить код черты модуля по нескольким файлам.Это может привести к некоторому шаблону.
- Это может заставить вас написать все приложение, используя эту парадигму.Прежде чем вы это узнаете, каждый класс должен будет смешать свои требования.
- Конкретная реализация должна быть известна во время компиляции, если вы не используете какое-то рукописное делегирование.Вы не можете динамически смешивать черту реализации, основываясь на значении, доступном во время выполнения.
Я предполагаю, что разработчики библиотеки не рассматривали ни один из вышеперечисленных вопросов как проблему, касающуюся Parsers
.