Fat vs Greasy (Was: [Zope-dev] Re: Future of ZClasses)
On 10/9/06, Dieter Maurer <dieter@handshake.de> wrote:
Philipp von Weitershausen wrote at 2006-10-7 23:51 +0200:
...
I find that the introduction of classes with (multiple) inheritance has been very economic. It was another concept but a highly fruitful one, despite the fact that they are not so liked in Zope3 land.
I think "fat" objects from mixing many different concerns into a single implementation are a failed approach.
Seeing how flexible you can be wit
a) separating concerns (functionality, responsibilities) into separate objects called components and
b) making the lookup of these components pluggable (using registries a.k.a. the Component Architecture),
I am almost convinced that in some years these registries will share the fate of acquisition: they will be seens as too much magic.
I expect this to happen as soon as Zope3 is becoming main stream and not only used by the fittest people.
I would not recommend anyone to over-use multiple inheritance as it's been done in Zope 2.
I am a strong favorite of (multiple) inheritance and use it excessively. I have the feeling that it makes me very productive.
There is of course no conflict between the two attitudes. It may *look* like there is, though. ;) In one case, you make loads of small objects with separate concerns, and merge them into one object by multiple-inheritance. In the other case you make loads of small objects with separate concerns and merge them via adapters. The first version is less flexible, as changing the behaviour of the resulting "fat" objects requires subclassing, while the other attitude can be hard to overview and grasp (and hence, I'll call it "greasy". Haha.) I think one generally should, in Zope3/Five, use objects as if they always need to be adapted. That is, you get the context, and you adapt it to whatever interface you need, with IMyinterface(context). Then, of course, you may very well make your object a fat object that implement all the bloody interfaces you need, instead of having multiple sets of objects and adapters, which in most cases just make things complicated. But with this attitde, that is make fat objects, but never assume they are fat when you use them, you can with little effort make something flexible. For example: The CalZope calendar attaches all views directly to the ICalendar interface. Only ICalendar objects can have these views. A calendar object in CPS is therefore a calendar that directly implements ICalendar, and some other extended interfaces with CPS support and stuff. This seems perfectly reaonable, but it turns out Plone people don't want that. They want ordinary folder to have these views. The solution to that is to attach all the views to "ICalendarViewable" and in all views make self.context = ICalendar(context), and this way adapt the context. By making my fat calendar objects IcalendarViewable, I need not to change any other code in CPSSharedCalendar or CalZope. I still have the same monolithic objects, that are easy to understand and debug. But for Plone, it would with these changes be perfectly possible to make adapters from Plone folders to ICalendar, and therefore use CalZope views for folders full of plone events. So, as long as you *use* the objects as if they always need to be adapted, you can very well write the objects monolithically if that suits you. So, heres a new tagline: "Use your objects as if they were greasy, and it isn't a problem if they are fat." ;-) -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.nuxeo.org/
Lennart Regebro wrote:
On 10/9/06, Dieter Maurer <dieter@handshake.de> wrote:
Philipp von Weitershausen wrote at 2006-10-7 23:51 +0200:
...
I find that the introduction of classes with (multiple) inheritance has been very economic. It was another concept but a highly fruitful one, despite the fact that they are not so liked in Zope3 land.
I think "fat" objects from mixing many different concerns into a single implementation are a failed approach.
Seeing how flexible you can be wit
a) separating concerns (functionality, responsibilities) into separate objects called components and
b) making the lookup of these components pluggable (using registries a.k.a. the Component Architecture),
I am almost convinced that in some years these registries will share the fate of acquisition: they will be seens as too much magic.
I expect this to happen as soon as Zope3 is becoming main stream and not only used by the fittest people.
I would not recommend anyone to over-use multiple inheritance as it's been done in Zope 2.
I am a strong favorite of (multiple) inheritance and use it excessively. I have the feeling that it makes me very productive.
There is of course no conflict between the two attitudes. It may *look* like there is, though. ;)
In one case, you make loads of small objects with separate concerns, and merge them into one object by multiple-inheritance. In the other case you make loads of small objects with separate concerns and merge them via adapters. The first version is less flexible, as changing the behaviour of the resulting "fat" objects requires subclassing, while the other attitude can be hard to overview and grasp (and hence, I'll call it "greasy". Haha.)
I think one generally should, in Zope3/Five, use objects as if they always need to be adapted. That is, you get the context, and you adapt it to whatever interface you need, with IMyinterface(context). Then, of course, you may very well make your object a fat object that implement all the bloody interfaces you need, instead of having multiple sets of objects and adapters, which in most cases just make things complicated.
But with this attitde, that is make fat objects, but never assume they are fat when you use them, you can with little effort make something flexible.
For example: The CalZope calendar attaches all views directly to the ICalendar interface. Only ICalendar objects can have these views. A calendar object in CPS is therefore a calendar that directly implements ICalendar, and some other extended interfaces with CPS support and stuff. This seems perfectly reaonable, but it turns out Plone people don't want that. They want ordinary folder to have these views. The solution to that is to attach all the views to "ICalendarViewable" and in all views make self.context = ICalendar(context), and this way adapt the context.
By making my fat calendar objects IcalendarViewable, I need not to change any other code in CPSSharedCalendar or CalZope. I still have the same monolithic objects, that are easy to understand and debug.
But for Plone, it would with these changes be perfectly possible to make adapters from Plone folders to ICalendar, and therefore use CalZope views for folders full of plone events.
So, as long as you *use* the objects as if they always need to be adapted, you can very well write the objects monolithically if that suits you. So, heres a new tagline:
"Use your objects as if they were greasy, and it isn't a problem if they are fat."
;-)
That's basically what I wrote the other day (The Times... ) : as an application designer you want a *plugin architecture* with greasy fat components, not an architecture with hundreds of micro-components wired together like this: http://jacobswellchurch.org/tim/archives/wires-bottom.jpg that require that learn the internals. Also, "plugin logic" is not the same as "micro-component logic": - plugins are single units that only need a runtime platform to get working, while micro-components need to get assembled before they can be used, the border between the platform and the platform's components is very blurry. - plugins have a public API that preserves backward compatibility, and hence preserves user's investments, while micro-components neither have a public or private API, they implement interfaces (interface != API) - plugins can get loaded and unloaded at runtime, or updated, while micro-components are basically added once at server startup time and they never get changed at run-time. - a plugin architecture can manage dependencies between plugins. - plugins are useful to market an architecture, (cf. Photoshop gimp, Gimp plugins, VDR plugins (http://www.cadsoft.de/vdr/plugins.htm), Firefox plugins, skins, Azureus plugins, Eclipse plugins ...). It is easy to explain what a plugin does in terms of functionality, while it is difficult to explain what a micro-component does. //- plugins encourage participation!!! (that's one of the reason of the success of Plone IMO: every one feel that they can create their own product, by looking at other existing products), while micro-components are difficult to grasp. - plugins can be used by end-users, while micro-components are designed by developers for developers. - ... /JM
On 10/9/06, Jean-Marc Orliaguet <jmo@ita.chalmers.se> wrote:
That's basically what I wrote the other day (The Times... ) : as an application designer you want a *plugin architecture* with greasy fat components, not an architecture with hundreds of micro-components wired together like this: http://jacobswellchurch.org/tim/archives/wires-bottom.jpg that require that learn the internals.
Also, "plugin logic" is not the same as "micro-component logic":
- plugins are single units that only need a runtime platform to get working, while micro-components need to get assembled before they can be used, the border between the platform and the platform's components is very blurry.
- plugins have a public API that preserves backward compatibility, and hence preserves user's investments, while micro-components neither have a public or private API, they implement interfaces (interface != API)
- plugins can get loaded and unloaded at runtime, or updated, while micro-components are basically added once at server startup time and they never get changed at run-time.
- a plugin architecture can manage dependencies between plugins.
- plugins are useful to market an architecture, (cf. Photoshop gimp, Gimp plugins, VDR plugins (http://www.cadsoft.de/vdr/plugins.htm), Firefox plugins, skins, Azureus plugins, Eclipse plugins ...). It is easy to explain what a plugin does in terms of functionality, while it is difficult to explain what a micro-component does.
//- plugins encourage participation!!! (that's one of the reason of the success of Plone IMO: every one feel that they can create their own product, by looking at other existing products), while micro-components are difficult to grasp.
- plugins can be used by end-users, while micro-components are designed by developers for developers.
That's not at all what I said. ;) But you have valid points and I basically agree with your separations of micro-components and plugins. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.nuxeo.org/
participants (2)
-
Jean-Marc Orliaguet -
Lennart Regebro