PicoContainer
  1. PicoContainer
  2. PICO-92

Remove parent -> children relationship

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.0-beta-5
    • Fix Version/s: 1.0-beta-4
    • Component/s: PicoContainer (Java)
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Two-way relationships and any form of circularities are hard to maintain. We should not have them unless they are strictly required.

      There's also some bugs in the current implementation and how it is used.

      These two current situations contradict each other:

      • One wants to be able to create a container temporarily with a parent in order to create for example a one-off instance or to keep as a request-scoped container in a web-framework. Without a downlink all you need to do is create that container, use it and the garbage collector will pick it up when it is no longer needed.
        To avoid this a weak reference is used from the parent to the children.
      • In most situations this is not intuitive. For example the XML-parsers (ehm... "front-ends"?) parse the xml-tree and then assume the hierarchy will be intact (for example when calling lifecycle-methods or in the unit-tests to validate the parsing was correct). Unfortunately this cannot safely be assumed.
        Personally I find that using weak-references in a design is a smell. It's to be used for system-level things like caching or distributed garbage collection.

      I've also encountered some scary issues relating to maintaining these relationship in PicoExtras. It is very common to do "addParent" when what you really want is "setParent", the relationship to the "old" parent is rarely maintained. I believe the relationship is contra-intuitive and we will see problems in the way it is used.

      We will see very scary bugs popping up due to all this.

      If the parent -> children relationship needs to be maintained I think we should instead provide some form of Builder-class (preferably in PicoExtras) that can be used to build and navigate the entire structure without having to add awkward relationships in the object-model.

      I don't think we should release a 1.0 before this is in some way resolved.

        Activity

        Jon Tirsen made changes -
        Field Original Value New Value
        Description Two-way relationships and any form of circularities are hard to maintain. We should not have them unless they are strictly required.

        There's also some bugs in the current implementation:
        The two current situations contradict each other:
         - One wants to be able to create a container temporarily with a parent in order to create for example a one-off instance or to keep as a request-scoped container in a web-framework. Without a downlink all you need to do is create that container, use it and the garbage collector will pick it up when it is no longer needed.
        To avoid this a weak reference is used from the parent to the children.
         - In most situations this is not intuitive. For example the XML-parsers (ehm... "front-ends"?) parse the xml-tree and then assume the hierarchy will be intact (for example when calling lifecycle-methods or in the unit-tests to validate the parsing was correct). Unfortunately this cannot safely be assumed.
        Personally I find that using weak-references in a design is a smell. It's to be used for system-level things like caching or distributed garbage collection.

        We will see very scary bugs popping up due to this.

        I don't think we should release a 1.0 before this is in some way resolved.
        Two-way relationships and any form of circularities are hard to maintain. We should not have them unless they are strictly required.

        There's also some bugs in the current implementation and how it is used.

        These two current situations contradict each other:
         - One wants to be able to create a container temporarily with a parent in order to create for example a one-off instance or to keep as a request-scoped container in a web-framework. Without a downlink all you need to do is create that container, use it and the garbage collector will pick it up when it is no longer needed.
        To avoid this a weak reference is used from the parent to the children.
         - In most situations this is not intuitive. For example the XML-parsers (ehm... "front-ends"?) parse the xml-tree and then assume the hierarchy will be intact (for example when calling lifecycle-methods or in the unit-tests to validate the parsing was correct). Unfortunately this cannot safely be assumed.
        Personally I find that using weak-references in a design is a smell. It's to be used for system-level things like caching or distributed garbage collection.

        I've also encountered some scary issues relating to maintaining these relationship in PicoExtras. It is very common to do "addParent" when what you really want is "setParent", the relationship to the "old" parent is rarely maintained. I believe the relationship is contra-intuitive and we will see problems in the way it is used.

        We will see very scary bugs popping up due to all this.

        If the parent -> children relationship needs to be maintained I think we should instead provide some form of Builder-class (preferably in PicoExtras) that can be used to build and navigate the entire structure without having to add awkward relationships in the object-model.

        I don't think we should release a 1.0 before this is in some way resolved.
        Hide
        Jon Tirsen added a comment -

        I've been having some problems fixing this issue. It is common in some unit-tests to navigate the parent -> child-link in order to check that a parsed or created structure is correct.

        I think the idea of creating a Builder-class that can be used to build and navigate a container hierarchy is the best solution to this problem.

        Suggestions are deeply appreciated!

        Show
        Jon Tirsen added a comment - I've been having some problems fixing this issue. It is common in some unit-tests to navigate the parent -> child-link in order to check that a parsed or created structure is correct. I think the idea of creating a Builder-class that can be used to build and navigate a container hierarchy is the best solution to this problem. Suggestions are deeply appreciated!
        Hide
        Paul Hammant added a comment -

        I'd like to stand in the way of this change.

        We used to have a componentised picocontainer (DefaultPC, LifecyclePC, Various adaptors, aggregators, composers, etc). When everything became amalgamated into one, this type objection was raised again and again.

        Just because someone has no need for parent->child /operations/ and child->parent resolution, does not mean nobody does.

        And whilst myself and Aslak are on vacation, I think we should advise caution on changes.

        Can I call a meeting in the week (F2F) to discuss things for Pico and Nano?

        Show
        Paul Hammant added a comment - I'd like to stand in the way of this change. We used to have a componentised picocontainer (DefaultPC, LifecyclePC, Various adaptors, aggregators, composers, etc). When everything became amalgamated into one, this type objection was raised again and again. Just because someone has no need for parent->child /operations/ and child->parent resolution, does not mean nobody does. And whilst myself and Aslak are on vacation, I think we should advise caution on changes. Can I call a meeting in the week (F2F) to discuss things for Pico and Nano?
        Hide
        Leo Simons added a comment -

        Paul wrote: "this type objection was raised again and again."

        That's not because people like to complain but because its a valid objection.

        The only usecase so far that requires a parent has references to its children is the PicoGUI; where it is required because PicoGUI needs to know the underlying graph structure.

        In daily use of picocontainer, I will argue that's a rather uncommon usecase (if you need to know the underlying structure at any other point than building it, that's a sign you need to thoroughly refactor your application: components are not supposed they care they live in a container, let alone in a container graph, let alone in what node of a container graph).

        Following the principle that uncommon usecases should not impact on the common usecases, the parent references child relationship is a natural subject of refactoring, since it is arguably complex to maintain (count the lines of code, and moreover the lines of code needed everywhere to test it, and finally the lines of codes needed everywhere to test it that don't exist).

        Now, I don't know much graph theory, but I believe that it's actually been proven by some smart person that the traversal usecase is best solved using a visitor.

        Going further:

        http://lists.codehaus.org/pipermail/picocontainer-dev/2004-January/001952.html

        refactoring pico to use 'parents' just like they are adapters makes the code a lot simpler but preserves all currently known use cases.

        I'm all for a pico release, keeping noses in the same direction and focussing on usecases, but I also strongly believe the objection remains a valid one.

        Show
        Leo Simons added a comment - Paul wrote: "this type objection was raised again and again." That's not because people like to complain but because its a valid objection. The only usecase so far that requires a parent has references to its children is the PicoGUI; where it is required because PicoGUI needs to know the underlying graph structure. In daily use of picocontainer, I will argue that's a rather uncommon usecase (if you need to know the underlying structure at any other point than building it, that's a sign you need to thoroughly refactor your application: components are not supposed they care they live in a container, let alone in a container graph, let alone in what node of a container graph). Following the principle that uncommon usecases should not impact on the common usecases, the parent references child relationship is a natural subject of refactoring, since it is arguably complex to maintain (count the lines of code, and moreover the lines of code needed everywhere to test it, and finally the lines of codes needed everywhere to test it that don't exist). Now, I don't know much graph theory, but I believe that it's actually been proven by some smart person that the traversal usecase is best solved using a visitor. Going further: http://lists.codehaus.org/pipermail/picocontainer-dev/2004-January/001952.html refactoring pico to use 'parents' just like they are adapters makes the code a lot simpler but preserves all currently known use cases. I'm all for a pico release, keeping noses in the same direction and focussing on usecases, but I also strongly believe the objection remains a valid one.
        Hide
        Jon Tirsen added a comment -

        "The only usecase so far that requires a parent has references to its children is the PicoGUI; where it is required because PicoGUI needs to know the underlying graph structure."

        It is a best-practice that a complex GUI (like a tree or graph-editor) should use some type of Builder pattern to work indirectly on the object model it is working on. That way new relationships, navigability directions, properties, optimizations can be added without the need to modify the underlying object model.

        I think this is the right solution to employ in the PicoGUI situation.

        Is there any other situation where this navigability is needed?

        Show
        Jon Tirsen added a comment - "The only usecase so far that requires a parent has references to its children is the PicoGUI; where it is required because PicoGUI needs to know the underlying graph structure." It is a best-practice that a complex GUI (like a tree or graph-editor) should use some type of Builder pattern to work indirectly on the object model it is working on. That way new relationships, navigability directions, properties, optimizations can be added without the need to modify the underlying object model. I think this is the right solution to employ in the PicoGUI situation. Is there any other situation where this navigability is needed?
        Hide
        Leo Simons added a comment -

        "Is there any other situation where this navigability is needed?"

        What are the common reasons to walk graphs? I think a few of those could apply to a pico environment.

        For example, I could imagine you would need it when building a framework on top of pico that imposes additional constraints, and wants to verify them at runtime when a user/client feeds an initialized picocontainer.

        I know of no such framework atm, nor do I have an intention to write one. But I'm sure that this and similar use cases can be solved with a visitor

        Another example is an avalon container built on top of pico that supports complex hierarchies (ie, something like merlin). Those beasties generally build and hold a directed graph in memory, and some advanced applications walk those graphs.

        But that's not a use case I'd worry about supporting too much

        Show
        Leo Simons added a comment - "Is there any other situation where this navigability is needed?" What are the common reasons to walk graphs? I think a few of those could apply to a pico environment. For example, I could imagine you would need it when building a framework on top of pico that imposes additional constraints, and wants to verify them at runtime when a user/client feeds an initialized picocontainer. I know of no such framework atm, nor do I have an intention to write one. But I'm sure that this and similar use cases can be solved with a visitor Another example is an avalon container built on top of pico that supports complex hierarchies (ie, something like merlin). Those beasties generally build and hold a directed graph in memory, and some advanced applications walk those graphs. But that's not a use case I'd worry about supporting too much
        Jon Tirsen made changes -
        Fix Version/s 1.0-beta-4 [ 10412 ]
        Fix Version/s 1.0 [ 10145 ]
        Jon Tirsen made changes -
        Component/s Core (Java) [ 10191 ]
        Jon Tirsen made changes -
        Assignee Jon Tirsen [ tirsen ]
        Aslak Hellesøy made changes -
        Assignee Jon Tirsen [ tirsen ] Aslak Hellesoy [ rinkrank ]
        Aslak Hellesøy made changes -
        Status Open [ 1 ] In Progress [ 3 ]
        Hide
        Aslak Hellesøy added a comment -

        This is implemented on the SINGLE_PARENT_REFACTORING branch. What remains to do is to make sure every container makes itself available as a ComponentAdapter.

        This will make it possible to register a child container as a component inside the parent container. Then, when the parent container is started via start() (PicoContainer extends LifeCycle), the child container(s) will also be started.

        A neat solution to a complex problem. The code is much cleaner now

        Show
        Aslak Hellesøy added a comment - This is implemented on the SINGLE_PARENT_REFACTORING branch. What remains to do is to make sure every container makes itself available as a ComponentAdapter. This will make it possible to register a child container as a component inside the parent container. Then, when the parent container is started via start() (PicoContainer extends LifeCycle), the child container(s) will also be started. A neat solution to a complex problem. The code is much cleaner now
        Aslak Hellesøy made changes -
        Resolution Fixed [ 1 ]
        Status In Progress [ 3 ] Closed [ 6 ]

          People

          • Assignee:
            Aslak Hellesøy
            Reporter:
            Jon Tirsen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: