cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Mazzocchi <stef...@apache.org>
Subject Re: [RT] composition vs. inheritance in blocks
Date Wed, 30 Mar 2005 00:05:00 GMT
Daniel Fagerstrom wrote:
> 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

If you are talking about

  block A extends block B

then the functionality that you describe above is already included in 
the original real block design and you don't even need the (ugly!) 
polymorphic protocol flavor, since the block protocol should takes care 
of all this transparently (thru the block dependency map of the block 
manager).

But (as usual), you jumped directly from that to

  block A extends block b *and* c

which, to me, is not the painless jump that you (and Peter) seem to suggest.

> This implies AFAICS multiple inheritance

not at all. you can have block 'cascading'/'wrapping' (you name it) 
without multiple inheritance.

> as you have to implement 
> polymorphism by hand if you use composition. 

No. Absolutely not. Go back and read all my emails about the block 
protocol: the functionality you describe is already there and doesn't 
require MI at all.

> 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.

see above.

> 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.

exactly.

>> 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. 

I completely agree that inheritance is useful. Dead useful. But single 
inheritance not multiple one.

> And it is no doubt easier to design 
> components than vertical frameworks, but that doesn't mean that we 
> should avoid designing framewoks.

hell no. I had enough 'build the framework before we even know where the 
problem is' avalonish crap in my life, thanks.

Until somebody proves me that this is no way to obtain a required 
functionality without MI, I'm -1 on it.

>> 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.

Sure, for cascading. Agreed. therefore 'single' inheritance.

>> 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.

and can you tell me why MI is supposed to help you achieving this?

>> 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.

Bingo.

> 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.

Very very true, and my argument is that MI moves the pain one step down, 
so that you never go thru exactly *that* design for reuse phase that 
composition forces you to go thru.

>> 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.

Very well, then we have composition (multiple implementation of 
interfaces) and single inherit
> 
>> 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
> 
> 
> 


-- 
Stefano.


Mime
View raw message