может помочь мне найти элегантный дизайн для разделения, перемещения и отслеживания объектов.
На рисунке ниже показан объект с начальным размером 100, который разделен на два (50, 75), затем один из дочерних объектов (75) впоследствии разделен на три (25, 25, 25).
Мой вопрос: может ли кто-нибудь придумать элегантный дизайн, который позволил бы мне из любого объекта пройти по всему дереву (например, чтобы идентифицировать корневого родителя из любого последующего дочернего объекта)?
Моя текущая попытка (см. Код ниже) использует поля экземпляра Parent и Children для отслеживания объектов, но, очевидно, она не дает мне требуемой функциональности - в Obj [Id: 6] я не могу рекурсивно найти корневого родителя .
Кто-нибудь может придумать решение? Я не думаю, что двойной связанный список будет работать, так как параметр spilled не ограничен только двумя.
Obj [Id:1, Size:100]
|
Split operation (50, 75)
<>
Obj [Id:2, Size:25] Obj [Id:2, Size:75]
|
Split operation (25, 25, 25)
<>
Obj [Id:4, Size:25] Obj [Id:5, Size:25] Obj [Id:6, Size:25]
public class SplitableObj : IEquatable<SplitableObj>
{
private Guid _id = Guid.NewGuid();
private int _size;
private SplitableObj _parent;
private List<SplitableObj> _childern;
public SplitableObj(int size)
{
_size = size;
}
public Guid id
{
get { return _id; }
set { _id = value; }
}
public SplitableObj Parent
{
get { return _parent; }
set { _parent = value; }
}
public List<SplitableObj> Children
{
get { return _childern; }
set { _childern = value; }
}
public int Size
{
get { return _size; }
set { _size = value; }
}
public IEnumerable<SplitableObj> Split(params int[] splits)
{
if (splits.Length < 2)
{
throw new ApplicationException("splits must be least 2.");
}
int totalSplits = 0;
foreach (int split in splits)
{
totalSplits += split;
}
if (_size != totalSplits)
{
throw new ApplicationException("Total splits must equal Size.");
}
foreach (int split in splits)
{
SplitableObj splitAmount = new SplitableObj(split);
splitAmount.Parent = this;
this.Children.Add(splitAmount);
yield return splitAmount;
}
}
public bool Equals(SplitableObj splitableObj)
{
if (splitableObj == null) return false;
return Equals(_id, splitableObj._id);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
return Equals(obj as SplitableObj);
}
public override int GetHashCode()
{
return _id.GetHashCode();
}
}