Scala сквозные обертки
Очень часто я хочу "заменить" один метод данного объекта.
foo: Foo
foo.bar(i) // original
foo.baz(s) // replace this implementation
Я закончу создание сквозного класса-обёртки.
class FooWrapper(foo: Foo) extends Foo {
def bar(i: Int) = foo.bar(i)
def baz(s: String) = foo.baz(s)
}
А потом
foo: Foo
val foo2 = new FooWrapper(foo) { def baz(s: String) = ... }
foo2.bar(i)
foo2.baz(s)
Это работает с чертами и классами и работает без изменения исходного кода типа.
Я использую это совсем немного, особенно при адаптации библиотек или других фрагментов кода.
Это может стать утомительным с множеством методов. На днях я хотел заменить shutdown
метод на ExecutorService
Например, и я должен был сделать это для дюжины методов.
Это распространенная идиома, или это обычно делается по-другому? Я подозреваю, что это можно сделать с помощью макроса, хотя я не нашел ни одного из существующих, которые бы это делали.
1 ответ
Вы можете достичь этого с помощью AOP (Аспектно-ориентированное программирование)
Для этого есть много библиотек, попробуйте эту - https://github.com/adamw/scala-macro-aop
- Обратите внимание, что эта библиотека сейчас находится в стадии POC, поэтому вы можете искать что-то более зрелое. Я поместил это здесь, потому что я думаю, что это показывает концепцию очень ясно.
Для вашего примера вам нужно сделать что-то вроде
class FooWrapper(@delegate wrapped: Foo) extends Foo {
def baz(i: Int) = ???
}