Древовидная структура данных ООП проблема проектирования (C #) - PullRequest
1 голос
/ 15 августа 2010

У меня проблема с конструкцией древовидной структуры, и я не могу придумать выход.

Я хочу иметь одно дерево классов, содержащее общие данные, и расширить класс Tree с помощью ComplexTree, который будет содержать больше методов, таких как Iterate, DoSomthingOnComplex и т. Д.

вот пример кода, который у меня есть:

class Tree<TData>
{
    public TData Data { get; set; }
    public ICollection<Tree<TData>> Children { get; private set; }

    public Tree<Data>(TData data)
    {
         // ...
    }

    public void Iterate(Action<TData> action)
    {
         action(Data);  
         Children.ForEach(x => x.Iterate(action));
    }
}

class ComplexTree<TData> : Tree<TData>
{
    public int ComplexValue1 { get; set; }
    public int ComplexValue2 { get; set; }

    public ComplexTree(TData data, int cv1, int cv2)
        : base(data)
    {
         // ...
    }

    public void DoComplexStuffOnTree()
    {
         // ... might want to use the base methods here
    }
}

проблема в том, что, с одной стороны, я не могу действительно предоставить коллекцию, содержащую Tree, любому, у кого есть ComplexTree, и я не могу использовать Iterate для ComplexTree, потому что я не могу использовать значения cv1, cv2, принадлежащие только к наследующему дереву.

Есть ли очевидное решение, которое я пропускаю? я не должен использовать наследование? следует переписать все методы?

Спасибо, John

1 Ответ

1 голос
/ 15 августа 2010

Трудно ответить на ваш вопрос, не зная фактического варианта использования, для которого вам нужна древовидная структура, но в целом я бы встал на сторону предложений, высказанных в комментариях:

  • Объявите класс ComplexData, содержащий ваши два целых числа, и объявите ComplexTree как подкласс Tree<ComplexData>.

  • Вы можете даже объявить ComplexData<TData> сам по себе универсальный, чтобы он мог содержатьдополнительные TData, а затем объявить ComplexTree<TData> в качестве подкласса Tree<ComplexData<TData>>.

  • Вам необходимо четко указать в контракте код для методов, которыеЗапустите ваши алгоритмы - то есть, какой метод на самом деле должен делать, в общих / абстрактных терминах, а не в терминах конкретного варианта использования.Если контракт заключается в том, что он возвращает коллекцию TData объектов, то, очевидно, именно это он и должен делать, независимо от того, запускаете ли вы его на простом дереве или подклассе.Если контракт является более абстрактным и поведение должно зависеть от подкласса, то, возможно, это должен быть виртуальный метод (или использование защищенных виртуальных методов), который подклассы могут переопределять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...