[weld-dev] Discussion on Delegate/Decorated types

Mark Struberg struberg at yahoo.de
Mon Dec 7 03:48:41 EST 2009


Gavin, for understanding why I read this different please look at 8.1.3 "Decorated types of a decorator":

"The delegate type of a decorator must implement or extend every decorated type"

plus
"The decorator intercepts every method:
•  declared by a decorated type of the decorator
•  that is implemented by the bean class of the decorator."

So this is why I assumed that the decorator type (the X thingy defined with @Decorate XDec implements X) defines the beans which are decorated. And please re-read the preamble of chapter 8, which many people read as the exact same: "A decorator implements one or more bean types and intercepts business method invocations of (all!) _beans_which_implement_those_bean_types_."! 

I read nothing from getting the delegated types (= in my read the bean types which should get decorated) from the @Delegate. But this is obviously the only way it could work. There may be many beans out there which e.g. implement Cat and Pet but would create a ClassCastException if the PetCatDecorator get applied (@Delegate SiamCat s <-boom for RussianForrestCat)

Anyway. We are now d'accord (hope so at least) that the decission which beans get decorated is: every bean which is assignable to the type of the @Delegate. (Thus Weld is implemented correctly for this part). This is really the most important part of the whole discussion. Please let's pin the
Q: "How to decide which bean instance get's decorated by which decorator" 
A: "Every bean that is assignable to the type of the @Delegate field in a decorator will be decorated by this decorator."

Pete, Marius: is this the way Weld is currently implemented?

Further thoughts: 
There is no need to check the decorator type (the X of @Decorator XDec implements X),because that must always be a subset of the @Delegate (see 1st sentence in 8.1.3) 
Which imho makes the decorator type basically useless - thus our question.
To repeat the argument: why using an interface to restrict the decorator to a few functions? Simply don't implement the functions you do not like to decorate! In fact the 2 parts are exactly _not_ orthogonal things because 1) is a pure subset of 2)!

Regarding the @Override argument. That's nice for some IDEs, but is Retention.SOURCE thus will get discarded by the compiler and helps us nothing at deploy time in the container...
To clarify this: we are surely talking about not only the fn-name but the whole signature of a function! 


I know its _very_ hard to form a short and precise definition, and my goal is not to rant about it, but to 
a) clarify what I misunderstood
b) @all: get a common understanding of what decorators are about (what did you have in mind basically)
c) give you a feedback about what sentences in the spec may be/get interpreted in a different way than you meant it.

txs and LieGrue,
strub

--- Gavin King <gavin.king at gmail.com> schrieb am Mo, 7.12.2009:

> Von: Gavin King <gavin.king at gmail.com>
> Betreff: Re: Discussion on Delegate/Decorated types
> An: "Marius Bogoevici" <mariusb at redhat.com>
> CC: "Mark Struberg" <struberg at yahoo.de>, "Weld-Dev" <weld-dev at lists.jboss.org>, "Pete Muir" <pmuir at redhat.com>
> Datum: Montag, 7. Dezember 2009, 8:31
> 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
> 

__________________________________________________
Do You Yahoo!?
Sie sind Spam leid? Yahoo! Mail verfügt über einen herausragenden Schutz gegen Massenmails. 
http://mail.yahoo.com 



More information about the weld-dev mailing list