jeudi 11 avril 2019

Stackable trait/decorator and abstract class

I have an abstract class (Java library) that takes constructor arguments and has a method called execute that I want to decorate:

public abstract class Task {
    private final String name;

    protected Task(String name) {
        this.name = name;
    }
    public abstract void execute(String str) throws Exception
}

And I have Scala classes that currently inherit previous one:

class FooTask extends Task("fooTask") {
  override def execute(String str): Unit = println(str + "foo")
}

class BarTask extends Task("barTask") {
  override def execute(String str): Unit = println(str + "bar")
}

Is it possible to write a decorator for a Task class like this:

trait TaskWithErrorLogging { self: Task =>

  override def execute(String str): Unit =
    Try(self.execute(str)) match {
      case Failure(exception) =>
        println("LOGGED " + exception)
        throw exception;
      case _ =>
    }

}

And then use it in order to log errors?

class BarTask extends Task("barTask") with TaskWithErrorLogging {
  ...
}

These tasks are being instantiated automatically by framework's injector, so there is no way to write new FooTask with TaskWithErrorLogging

Currently, decorator's overriden method is being ignored (it compiles, but does not execute). Adding abstract modifier to the method in decorator does not compile. What is the right way to implement this logging solution? Maybe there is another option except for a stackable trait?

Aucun commentaire:

Enregistrer un commentaire