Thanks Salvin, but if you were to check out the composite pattern and my example they are not the same. My issue does not involve part-whole hierarchies where an abstract class is needed to represent primitives and their containers. Mine is a style question I would think.
marten kay wrote:My issue does not involve part-whole hierarchies
I think it does actually,
you have a one-to-many relationship between a sheet and a selector,
then you have a one-to-many relationship between a selector and a declaration,
then you have a one-to-many relationship between a declaration and an action
Sounds like you shouldnt just be using collections to manage the whole thing...
Thanks Salvin - but from what I understand the classic composite pattern has leaves and composites of the same type. The difference here is that there are no leaves and each composite is of a different type. But your reply got me thinking and I now have a solution involving Generics.
My problem now is, how can the following generic type be extended from 3 levels to n levels. Would generics allow this, and if so, how? Is it possible to have a variable number of Types in the class declaration?
Anything can be composited. In any case, to me it looks like you're using maps as a replacement for OOP--I find that kind of thing painful in Java.
I'd feel the same way about a chain of non-obvious gets--I'd rather deal with actual objects with rational property names. But I don't really find a get(foo, bar, baz) to be much of an improvement--I'd actual prefer the get trainwreck because then it's obvious I'm diving into an object hierarchy, whereas with the single method I'm relying on memory and hope.
I'm with Salvin--and it's the logical conclusion of your last two alternatives taken to their clean, OOP implementation.
In this application three parameters are always required for each get (get a String id to be inserted as xhmtl element id), so the 'get trainwreck' alternative will still require three gets .
Also, I am always reminded of Joshua Bloch 2nd Ed p81 where he states"Favor composition over inheritance", so the OO versus maps argument is moot.
I'm also interested in your statement"
Anything can be composited
Sure, but in the common composite pattern the leaf and composite need to subclasses of the same component, which is not the case here. So I'm still thinking that while everything can be composited , the composite pattern does not always apply... but perhaps I'm mistaken
marten kay wrote:Also, I am always reminded of Joshua Bloch 2nd Ed p81 where he states"Favor composition over inheritance", so the OO versus maps argument is moot.
"Moot" is a word I've never been comfortable with in this usage since one of its meanings is "to consider carefully". That aside, I don't get your point or how that maxim renders what Salvin and I are saying irrelevant.
Anything can be composited
Sure, but in the common composite pattern the leaf and composite need to subclasses of the same component, which is not the case here.
The composition-over-inheritance basically says "instead of your Foo sub-classing Baz, put a Baz in your Foo." Venners' example is a button event handler where you don't subclass a button to get your behavior, you plug in a listener--there's *some* inheritance (the listener interface)--but it's tiny. I've never seen anything anywhere that says or implies composition should only composite "similar" types.
If maps upon maps is your best option, then use it, and deal with the maintenance issues. Like I said--what we're saying is what your last options were, but moved into OOP realm, and extended. (Plus heavily-nested generics make my eyes bleed.)
If it's an issue of undersanding code later, and you can't make the code clear enough, then comment it. I'd rather I didn't *need* to comment something, because inevitably it will be wrong--if not now, then in the future. I'd rather see idActionMap.getSheet(foo).getSelector(bar).getDeclaration(baz).getAction(plugh)--but Demeter would not be happy.
To *me* the hierarchical nature of what you're doing is syntactically missing in idActionMap.get(foo, bar, baz, plugh)--but it *does* wrap things up, at least in the "end-user" code.
Salvin and I are also operating at least somewhat in the dark, since we don't know the ultimate purpose of what you're doing--we're just guessing.
Through the maxim I don't mean to render what you are saying irrelevant, quite the contrary, I'm just trying to illustrate where I am coming from.
In terms of the ultimate purpose, I'm writing a web interface to manage style sheet information that is stored in a database. So I use something like the following for rendering the xhtml input form
so there is only ever one type of get.
Anyhow, this is a bit academic as I have a managable but perhaps not ideal solution, and I greatly appreciate Salvin's and your input, because I have learn't a lot about generics and the composite pattern now. But there are a lot more things that I need to get....