3

I was refactoring some java to use decorators. All of the decorators inherited from a class ThingDecorator, let's say. This consisted entirely of:

SomeType methodName(OtherType otherThing) {
    return decoratedObject.methodName(otherThing);
}

For maybe 20 methods of that form. This is like writing "this thing is a decorator" over and over again, which just drives me nuts as a DRY enthusiast. Every addition to the activities of this class needs an addition to the class[es] that form the basic un-decorated behavior and the decorator, but it's always just "this thing is still a decorator!" all over again. Is there any way to express once that an object is to delegate all non-overridden methods to some member field?

5
  • You might be able to do it with a compile time annotation, not certain. However, even if you could, it would confuse IDEs something horrible.
    – user40980
    Commented Nov 28, 2015 at 3:38
  • Unless the base decorator is a class stating the contract, I see no reason why you would want to inherit from it, you might as well just use an interface. This seems like a violation of LSP.
    – Andy
    Commented Nov 28, 2015 at 7:10
  • @davidpacker for the purpose of the question it doesn't matter, but the real project had an interface AbstractThing that was the contract, a BasicThing implements AbstractThing that was the default behavior of a Thing, a ThingDecorator implements AbstractThing whose only task was to have a reference to an AbstractThing and delegate all calls to it, a plethora of ThingWithSomeStuff extends ThingDecorator which provided only the concrete meaning of the Thing having some Stuff, and finally a ThingToPointAt for hiding the decoration from things that don't know they need it.
    – sqykly
    Commented Nov 28, 2015 at 13:02
  • @davidpacker (cont) in the more complete picture, it should be clear that both levels of abstract hierarchy are puposeful - the interface defines the contract, the BasicThing fulfills the contract provided by the interface, the abstract base decorator ensures that any concrete decorator that doesn't fulfill the entire contract has a reference to a thing that can and uses it to do so without needing to understand the entire contract of a Thing when all you want is for it to have some Stuff.
    – sqykly
    Commented Nov 28, 2015 at 13:32
  • @davidpacker final clarification because that sounds overcomplicated otherwise: there were many different kinds of Stuff that could affect a Thing and many different kinds of Thing, and new kinds of Stuff were being added with every revision. Before I got there, all Stuff had to be defined, considered, and managed throughout the Thing that it affected. It was already quite complicated, my way is actually a lot neater.
    – sqykly
    Commented Nov 28, 2015 at 13:55

1 Answer 1

2

No, unfortunately, there isn't any way to accomplish this.

Unless you use some magic, like this: michael.gr - Intertwine: Normalizing Interface Invocations (which though I have implemented for C#, not for Java yet.)

2
  • I hover around the use of magic (technically I guess it's code generation or macros, though we don't like using the word anymore thanks to C) and hesitate because I worry that no one will ever be able to just pick up my code and read it knowing plain old java. Right after I wrote this question, I wrote a sweet.js macro for it, but I just know that as dry and beautiful as it is, I can never use it in a serious project. Depressing.
    – sqykly
    Commented Nov 28, 2015 at 4:05
  • I am giving the question a little more time, but I am not forgetting a check mark for the "there is no answer" answer if no one can come up with some miracle.
    – sqykly
    Commented Nov 28, 2015 at 6:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.