Question:
It is necessary to implement a pattern builder for a tree-like data structure. Everything I've tried shows that this is very difficult to do and extremely inconvenient and much easier to do after a few new. I would be very happy if someone solved similar problems and showed an example of such a builder.
Answer:
Let's say we want to build a tree. We have a node
public class Node
{
public int Value { get; set;}
public Node Left { get; set;}
public Node Right { get; set;}
}
Below is an example of a fluent builder. That is, calls can be combined into chains to build a tree
public class TreeBuilder
{
private InnerNode _root;
private InnerNode _currentNode;
private TreeBuilder(int value)
{
_root = new InnerNode() { Value = value };
_currentNode = _root;
}
public static TreeBuilder Create(int value)
{
return new TreeBuilder(value);
}
public TreeBuilder AddLeft(int value)
{
_currentNode.Left = new InnerNode() { Value = value, Parent = _currentNode };
return Left();
}
public TreeBuilder AddRight(int value)
{
_currentNode.Right = new InnerNode() { Value = value, Parent = _currentNode };
return Right();
}
public TreeBuilder Left()
{
_currentNode = _currentNode.Left;
return this;
}
public TreeBuilder Right()
{
_currentNode = _currentNode.Right;
return this;
}
public TreeBuilder Root()
{
_currentNode = _root;
return this;
}
public TreeBuilder Parent()
{
_currentNode = _currentNode.Parent;
return this;
}
public Node Build()
{
return Build(_root);
}
private Node Build (InnerNode node)
{
if (node == null) return null;
return new Node() {Value = node.Value, Left =Build(node.Left), Right=Build(node.Right)};
}
private class InnerNode
{
public int Value { get; set; }
public InnerNode Left { get; set; }
public InnerNode Right { get; set; }
public InnerNode Parent { get; set; }
}
}
Inside the builder, to represent an incomplete tree, I used a separate class, since this class has a link to the parent and it is more convenient to walk through the nodes with it. In theory, it was possible to accumulate information about the object under construction as you like.
Well, actually, the use of:
var root = TreeBuilder
.Create(10)
.AddLeft(5)
.Parent()
.AddRight(15)
.AddLeft(10)
.Build();
// 10
// / \
// 5 15
// /
// 10