[weld-dev] Discussion on Delegate/Decorated types

Gavin King gavin.king at gmail.com
Mon Dec 7 02:31:49 EST 2009


On Mon, Dec 7, 2009 at 2:04 AM, Marius Bogoevici <mariusb at redhat.com> wrote:

> Overall, it seems like there are two competing restrictions at play: that a
> decorator can decorate only methods defined on the decorated types (so
> methods which are not on the decorated types will be ignored) and it can
> decorate only beans which are injectable as delegates.

I don't understand how these restrictions are competing, and I don't
understand your doubt. The decorated types identify the methods that
are intercepted. The delegate injection point identifies the beans
that are decorated. There is no overlap here. These are orthogonal
things.

> It should be noted that, according to Mark, quoting Pete (and I can see the
> same in the code) - Weld does not look at the interfaces implemented by the
> @Decorator bean in order to retrieve the decorated types, but it infers them
> from the type of the delegate.

That definitely doesn't sound right to me. That's not what the spec
says. The delegate might implement some interface that is not
implemented by the decorator, and is hence not a decorated type.

> Now, it may happen that a method is defined on the decorator and the target
> class, but not on any type implemented by the decorator - according to a)
> and 8.1.3, it won't be used to decorate anything. But in Weld, for example,
> since the decorated types are inferred from the @Delegate, it will be used
> for decoration anyway,.

If true, that would be a bug. That is not what the spec says. The spec
is the source of truth here, not Weld!

> The main question raised by Mark during the discussion was what is the use
> for having the Decorator implement an interface, when for practical
> purposes, the decorated types are indicated by the delegate type.

No, they are not. The delegate attribute may implement additional
types that are not decorated types. And this is *useful*.

> Furthermore, if a decorator decorates more than one type/interface, what is
> the type of the injected delegate?

It must be a subtype of all the decorated types. The spec says this
*explicitly*.

> The only possible solution now is a type
> which implements/extends both interfaces, which means that only a bean of
> that class or a subclass of it (including implementors if we're talking
> about an interface) can be decorated. Apparently, this is possible because
> of the gap in the specification that Gavin mentioned yesterday, which allows
> concrete types to be delegates.

An interface can be a subtype of other interface types. I really don't
get your point.

> If the gap was closed by eliminating
> concrete classes, then you can't have a decorator that decorates more than
> one interface.

Definitely not true.

   interface X extends A,B {}

> The delegate type restricts the eligible beans anyway (only beans that
> implement/extend this class are eligible), but why is then necessary to
> indicate a number of interface types which can be decorated? My take on this
> is that you may not want to decorate all methods on the delegate, only
> certain methods and requiring the decorator bean to state the interfaces it
> wants to decorate can be used for that purpose.

Right.

> But Mark has a point here,
> that you can achieve the same result by just not implementing those methods,
> so the requirement for the decorator to implement certain interfaces could
> be considered superfluous.

You've really, really lost me here. WTF would I not want to implement
the interface? Aside from this just being a totally normal and natural
thing to do, this makes my code typesafe (when I add @Override), and
lets my IDE fill in the method signature for me.

Suppose the interface X declares a method void foo(), and I'm going to
implement that same method on a class D (my decorator). Why would I
not want to say D implements X? How the hell can the CDI impl be sure
that this method named foo() is actually the method X.foo(), and not
some other method that just happens to have the same name? This is not
fucking Ruby. Java is a statically typed language. We identify methods
by type+name+signature. Not by name alone.

What exactly are you trying to achieve here? What is wrong with having
a decorator implement the interface it is intercepting? Why would I
ever want to do it any differently?


> c) Samples
> Let's look at an example provided by Mark:
> class Cat { String getName() {return "";}};
> class AngoraCat extends Cat { boolean getHairLength() {return true}}
> class SiamCat extends Cat { };
> @Decorator CatDecorator { @Delegate Cat c; String getName() {
> log.info("something"); return c.getName(); } }
>
> Now, looking at this sample it seems like:
> (ASSERTION 1) In the sample above there are no decorated types, therefore no
> actual decoration takes place.

Correct.

> Let's add Pet, an interface and have Cat implement it
> class Pet { String getRegistrationNumber()};
>
> (ASSERTION 2) The set of decorated types consists of the interface Pet.

Not correct. Not unless CatDecorator implements Pet.

> Now let's consider the following two decorators:
>
> @Decorator PetDecorator implements Pet {@Delegate Pet p; String getName() {
> log.info("something"); return c.getName(); }}
> @Decorator CatDecorator { @Delegate Cat c; String getName() {
> log.info("something"); return c.getName(); } }
>
> (ASSERTION 3) With the modification above, both PetDecorator and
> CatDecorator apply to all types of cats, but PetDecorator also applies to
> Pets which are not Cats

Correct. But note that CatDecorator has no decorated types.

> Now, if we had:
> interface Cat { String getName();};
> class SiamCat implements Cat, Pet { };
> class RussianForestCat implements Cat, Pet { };
> @Decorator PetCatDecorator implements Cat,Pet {@Delegate SiamCat c; String
> getName() { log.info("something"); return c.getName(); }}
>
> (ASSERTION 4) PetCat will decorate SiamCat but not RussianForestCat (won't
> even be picked up as a decorator since it does not meet 8.3 wrt
> RussianForestCat

Correct.



-- 
Gavin King
gavin.king at gmail.com
http://in.relation.to/Bloggers/Gavin
http://hibernate.org
http://seamframework.org


More information about the weld-dev mailing list