Шаблон для разделения, перемещения и отслеживания объектов

c# design-patterns

214 просмотра

2 ответа

0 Репутация автора

Кто-нибудь может помочь мне найти элегантный дизайн для разделения, перемещения и отслеживания объектов.

На диаграмме ниже показан объект с начальным размером 100, который разделен на два (50, 75), затем один из дочерних объектов (75) впоследствии разделен на три (25, 25, 25).

Мой вопрос: может ли кто-нибудь придумать элегантный дизайн, который позволил бы мне с любого объекта пройти через все дерево (например, идентифицировать корневого родителя от любого последующего дочернего объекта)?

Моя текущая попытка (см. Код ниже) использует поля экземпляра Parent и Children для отслеживания объектов, но, очевидно, она не дает мне требуемой функциональности - в Obj [Id: 6] я не могу рекурсивно найти корневого родителя.

Кто-нибудь может придумать решение? Я не думаю, что двойной связанный список будет работать, так как разлитый параметр не ограничен только двумя.

                      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();
    }
}
Автор: csharpdevguy568 Источник Размещён: 18.11.2008 01:10

Ответы (2)


0 плюса

156 Репутация автора

Почему у вас возникают трудности с поиском рута? переходить от родителя к родителю, пока родитель не будет установлен.

Кстати, вы говорите о деревьях B +? Они автоматически балансируют, используя блоки детей, которые разделяются при превышении порога. Посмотрите на это изображение в Википедии.образ

Автор: thAAAnos Размещён: 18.11.2008 01:13

1 плюс

41709 Репутация автора

Домашнее задание?

set RootObject to the current object.
while the parent of RootObject is not undefined, set RootObject to its parent.
Finally, return RootObject.
Автор: Svante Размещён: 18.11.2008 02:57
Вопросы из категории :
32x32