cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Fagerstrom <dani...@nada.kth.se>
Subject Re: [RT] composition vs. inheritance in blocks
Date Tue, 29 Mar 2005 18:23:25 GMT
Stefano Mazzocchi wrote:

> Daniel Fagerstrom wrote:

<snip/>

> I don't like multiple inheritance and this is not just because I 
> learned OOP thru java, but because every single time I wish I had 
> multiple implementation inheritance in java I found a way to go around 
> the problem with single implementation inheritance that was more elegant.

I learned OOP thru C++, so I even have had the possibility of using 
multiple implementation inheritance, not just the work arounds ;) And in 
most cases composition is better than multiple implementation 
inheritance, but in the cases where you merge two different concern 
areas it is useful and natural according to my experience. While I don't 
find the "extend the largest abstract base class and repeat the 
interface and delgate to the other" ideom used in Java particulary elegant.

But, although I believe that we should use well known concepts from OO 
as much as possible in the design of blocks, as we know some of the 
consequnces of them and as they are familiar to the users, we must be 
aware about that blocks and typical objects have quite different levels 
of granularity and are not completely analogous.

                                    --- o0o ---

So what I propose is that "extend and override" is a convenient and 
productive way to build webapps. You start from a working default 
application and add your own data and modify the behaviours that you 
need to modify. If you have used Forrest, you know what I'm talking 
about. But the difference between Forrest and what I propose is that you 
don't need any complicated sitemap tricks and global configurations with 
search paths, if we makes the block polymorphic.

                                    --- o0o ---

This is not just armchair speculations from me. We have built a number 
of webapps during the last year based on sitemap polymorphism. The 
mechanism is rather simple, in the sitemap of the base application we 
use a variant of the cocoon protocol:

cocoon:polymorph:/foo.xml

that basically calls

cocoon://<sitemap-path>/foo.xml

by mounting the base application in the end of the "extending" sitemap, 
the polymorph sitemap rules can be overrided just by defining the uri in 
the before the mount.

Its easy and works well. Of course one have to do some thinking to build 
a reusable base application, but that goes generally for reusability.

We started to use this pattern because we had a webapp, that a number of 
customers wanted slight variations of. In the beging we just made the 
new webapps extend a slight abstraction of the original webapp. Not 
because I thought it was a good idea, but more because of time 
constraints. Our experience is, hardly supprising, that it is more 
flexible to base your webapp on a number of orthogonal vertical 
frameworks. So we have factored out some such from the original webapp.

                                    --- o0o ---

So our experience is:
* extend and override is productive
* vertical frameworks are easier to reuse

This implies AFAICS multiple inheritance, as you have to implement 
polymorphism by hand if you use composition. If you have better ideas 
about how to achive default behaviour that is easy to override, I'm of 
course interested to discus them instead.

We have only used polymorphism on sitemap level, if it is usefull for 
components is another question, I would assume that, but it needs 
further thinking.

> I would go a little further and say that I believe inheritance is 
> useful only when used as a 'cascading' mechanism, in any other sense 
> is harmful: composition should be used instead.
>
> Why so?
>
> It's extremely hard to design for inheritance, a lot easier to design 
> for composition.

These are different concerns. Of course we should support composition, 
no doubt about that, but based on the reasons and experiences described 
above I want inheritance as well. And it is no doubt easier to design 
components than vertical frameworks, but that doesn't mean that we 
should avoid designing framewoks.

> And performing composition thru multiple-inheritance is a really 
> terrible way to do it. Why? because you need to go very deep in 
> describing what behaviors get exposed and what are protected, 
> otherwise things get messy very fast.

Sure, it is well known deep hierarchies of implementation inheritance 
often leads to problems. People tried to use it as "the golden hammer" 
once, but that doesn't make it less usefull for what it is good for.

> Also, multiple-inheritance stops further composition: you seem to 
> suggest that a block that inherit multiply is a 'leaf block', one that 
> is your own application and that will not be used by others.

Yes, that is correct, I want it to be as simple as possible to put 
together a webapp based on ready made vertical frameworks.

> Well, one of the reasons for block design was to sparkle the creation 
> of reusable application components without people to think much about 
> them: multiple-inheritance yields horizontal behavior changes to the 
> inherited components, which means that if I have block A inherit block 
> B and then block C that wants to use A but was already using B, but A 
> modified B's behavior a little with the inheritance, you have a problem!

Sure, you have to keep your blocks orthogonal to make them reusable, 
overlapping behaviour leads to a mess.

But honestly, reusabillity has been considered a major topic in the 
software business for a number of decades. We all know that it doesn't 
happen spontaniously, you have to design for it and you have to reuse 
your component or framework a number of times and make lot of 
improvements before it becomes more generally reusable.

> I am strongly against multiple implementation inheritance for blocks, 
> because what you want to do, if you care about reusability, is really 
> multiple composition and that is achieved with being allowed to 
> implement multiple behavioral interfaces.

Of course I want to support that as well.

> If you *don't* care for reusability, then it's true that multiple 
> implementation inheritnace can serve as a cheaper form of composition.

For the majority of Cocoon users I would assume that blocks that are 
possible to extend and override is easier to reuse (considered that they 
have a good design of course), than just a lump of components and 
stylesheets.

> But if I had to pick between improving block reusability or ease of 
> composition, I would go with the first, hoping that tools/syntax-sugar 
> would help the second (as it happened with Java).

It's not either or. It's not exactly rocket science to build a mechanism 
for mutiple inheritance so we can have booth.

We just need to discuss what we want to achieve and how to achive it to 
get it right.

/Daniel



Mime
View raw message