Sébastien Lorion <[EMAIL PROTECTED]> wrote:

> public interface IReadOnlyTree
> public interface ITree
> public interface ITreeNode

I understand what you're aiming at, though I have to say that my
positive experiences with functional styles of programming and my
negative experiences of the XML DOM have turned me off this kind of
approach. I think interfaces aren't suited to this. You can't just have
any old class implement an ITreeNode interface and expect it to live in
the tree, because to actually implement the interface, it needs to know
about the concrete implementation of ITree & friends. Thus, you're
typically forced to go down the tree node factory route, with all its
associated non-functional-ness and XML DOM horribleness.

By non-functional-ness, I mean: one of the nicest things about trees is
that they're recursive and eminently suitable to functional-style
programming. Writing a tree pattern matcher, tree rewriter, etc. is a
joy when nodes are simple and recursive. Having to go through a
factory/owner to create nodes, and having to pass that factory/owner
around, makes writing traversal and rewrite routines a little too heavy
and Java-y (in the bad, "enterprise" way) for my personal taste.

I'd consider using containment / aggregation, rather than interfaces, to
get what you're after.

> In the case where the relationships are stored centrally, the nodes are much
> more lightweight in term of code as most operations gets delegated to the
> tree and there is no need to have internal methods.

If the relationships are stored centrally, it seems to me that there's
no need for your nodes to implement any interface at all - they can
simply be System.Object. That would appear to me to be a better
approach; you could then use a proxy class (I'd choose a concrete sealed
one rather than an interface) to work with the nodes.

Above all, I'd try to avoid generalizing too early. I've come to think
that interfaces being used pervasively, very early in a design, is a
sign of too much generalization too soon.

> In the tree-as-a-node approach you describe,
> 
> I am curious about where exactly you store the relationships between the 
> nodes.
> I get the general idea and it is something I have explored, but
> I would like to have more details on your implementation.

The nodes store the relationships; typically as either a (possibly
sparse, i.e. created on demand) List<> of children, or as a FirstChild
and NextSibling tuple just like a Lisp cons cell.

Here's an idea (using public fields for exposition):

// In library:
public class TreeNode<TNode> // maybe ': XxxNode' for extra polymorphism
    where TNode: TreeNode<TNode>
{
    public TNode FirstChild, NextSibling; // or other implementation
    // as you desire
    
    // other stuff for algorithms can be added here without
    // versioning problems interfaces have
}
// maybe have different base classes for different implementations

// In user code:
public class BaseNode : TreeNode<BaseNode> 
{
    // common functionality etc.
}

public class MySpecificNode : BaseNode
{
    // ...
}

-- Barry

-- 
http://barrkel.blogspot.com/

===================================
This list is hosted by DevelopMentor®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to