Lukas,

To clarify for you, the extra database accesses are because when the database accesses a PRDecorated node it loads the decorations in. Then seeing that PRChildren is present it generates a second access to get the contents of PRChildren only to find that it is empty. This is extra work (and time) for no net purpose.

At the moment the problem is that many operations that involve children are doing so via PRStructure-#childrenDecoration whose default behaviour is to add an empty PRChildren instance to its decorations even if it is not actually needed.

To be honest I love the clean design, even with empty PRChildren instances. It's just a shame when pragmatic considerations mess with our nice designs. Since I indicated that there are other ways of solving this problem I will list a few below.

I constructed the children-accessing interface in order to satisfy the needs of the users of #childrenDecoration which are primarily the commands and the tests. Specifically:

PRCommand-#validateName: aString of: aChildStructure in: aStructure
PRCommand-#uniqueName: aString in: aStructure

PRChangeEnvironmentCommand-#doExecute
PRAddCommand-#doExecute
PRCopyCommand-#doExecute
PRMoveCommand-#doExecute
PRStructure-#remove

Solution Options:

1. child-accessing interface as discussed.

2. Magma before serializing any PRDecorated looks to see if there are any empty PRChildren and removes them before writing to its buffers. [ I think that this will work , though I am not 100% certain, but then we have PRChildren being created and destroyed over and over.]

3. Use an interface such as

aStructure withChildren: [ :children |  children add: ( aNewPage ) ]
where #withChildren: cleans up afterwards.

4. Rewrite the commands above to use some form of visitor as you suggest below:
                                     

I wonder where from these children are accessed? No part of the code  
should directly access the children of a structure, but instead walk  
over them using a visitor. Of course, I might have missed something ...
 
Note that subclasses of PRStructure might override  
#childrenDecorationClass to use a completely different decoration for  
children.

  
fair enough.


  
and an access interface defined for children...

#addChild:
#childAt:
#childAt:ifAbsent:
#childAt:ifPresent:
#childrenIncludes:
#removeChild:
    

I don't see why this would help. As far as I see none of my code uses  
any of this functionality directly.
 
I think that you forgot the command actions #doExecute etc. see above
It is not the way Pier is designed. Compared to SmallWiki I wanted to  
factor out all the behavior related to children to a different  
(pluggable) object
Fair enough, I thought as much, but when I found PRStructure-#addChild: it indicated to me that you had thought of having a child-accessing interface of sorts, and so I simply completed the set to provide the functionality actually used in the image.

I had a look at the third option and this is what I came up with

PRDecorated>>newDecorationOfClass: aClass in: aBlock
| decoration result |
decoration := aClass new.
result := aBlock value: decoration.
decoration isEmpty ifFalse: [ self addDecoration: decoration ].
^result

PRDecorated>>decorationOfClass: aClass in: aBlock
| decoration result |
decoration := self decorationOfClass: aClass
        ifAbsent: [ ^self newDecorationOfClass: aClass in: aBlock ].
result := aBlock value: decoration.
decoration isEmpty ifTrue: [ self removeDecoration: decoration ].
^result

PRStructure>>childrenIn: aBlock
^ self decorationOfClass: self childrenDecorationClass in: aBlock

and so this enables things like

PRCommand>>uniqueName: aString in: aStructure
    "Answer an unique structure name with the prefix aString within the parent aStructure."

    | index name |
    (aStructure notNil
        and: [ aStructure childrenIn: [ :children | children includes: aString ] ])
            ifFalse: [ ^ aString ].
    index := 1.
    [ aStructure childrenIn: [ :children | children includes: (name := aString , ' ' , (index := index + 1) asString) ] ]
        whileTrue.
    ^ name

would that be better?

Keith