There are three reasons: Reason #1. There Are No Number 3. I like very much polynesian counting system which includes only numbers 'one', 'two' and 'many'. It has much sense in computing environment. One is simple variable. Two is a pair: {key:value}, (a,(b,(c,d))), object.method and so on. The many is all the rest. How it related to ZPatterns? Look: 1. we have *Rack* (level 1) 2. Rack is inserted into (used by) *Specialist* (level 2) 3. Specialist can be inserted into other Specialist, but to do it we have change Specialist's type (by replacing retrieveItem method). This is definitely changing of the type because the Specialist gets new message handler (and changes the signature). Doing this we get new *ModifiedSpecialist* (level 3). If we think about two chained specialists we see all the three levels--not one, not two, not many. There should not be 'three' or 'four' or 'twenty five' levels, I repeat again: one, two, or many. Reason #2. Allow People Implement ZPatterns Algebra! Specialists are Aspects. They are much like colored filters which breath the life into black-and-white pictures. Let's think about the stack of filters (chain of Specialists again). What do we see? First filter in the stack (Rack) slightly differs from others. It is much like terminator in the chain or, from the other end, the source of pictures. See again. Second filter differs from third and four. Why? Third and four have added 'retrieveItem' method and second has not. This should be reimplemented in way which allow painless stacking of the Specialists, and Rack should be special case of Specialist, which allow no further cascading. Moreover, Rack is 'colorless' filter with the 'image' (DataSkin) on its back side, which 'weaves' no aspects but StorageIndependentPersistence. Let me invent a small algebra. 1. Let us define a space of roles with points having coordinates R=(r1,r2,...) where R is 'role meanings' vector or somewhat in this sense. 2. There is a zero value with sense 'no role'. If object (point) has no roles at all it's in the (0,0,...) point. The ZPatterns zero is DataSkin. 3. Let us define set of operators F which are transforming point coordinates by changing role meanings. R' = F( R, P), P = (p1,p2,p3...) where P is parameter vector. 4. Let our operators be instantiable: Fp(R) = F( R, P), P=(p1,p2,...) 5. Now we can do composition: R' = Fa( Fb( Fc( R))), which can mean in real life: ThisContextRole = ShoppingCart( Client( ZSession( Rack( DataSkin)))) Looks good? I think yes. The only obstacle is the Rack-Specialist incompatibility. Reason #3. I'm too lazy to write retrieveItem each time I need compose Specialists - I do it too often :-) ==================================
(Note, by the way, that the DataManager interface doesn't support getItem/newItem, so I can't just make Specialist use DataManagers. Customizers, for example have no idea what objects they're customizing, so they can't support getItem.)
I suggest you set up this (or similar) hierarchy which solve the problem: DataManager DataSouce Specialist Rack and replace 'Racks' tab with the 'DataSources' tab. Mike