Здравствуйте, AlexGin, Вы писали:
AG>>Для представления древовидных структур, с коллекциями элементов того же типа, что и корневой элемент?
AG>>Когда в корневом элементе требуется иметь коллекцию child-элементов.
BFE>>Не вижу препятствий.
AG>Элемент дерева, как логично я заметил выше, один и тот же.
AG>Для каких-то других элементов — он является parent-ом.
AG>Для других — чайлдом.
AG>Ссылочку на этот чайлд хранит родитель (parent) в своей коллекции.
Тогда смотрите ответ Точки.
AG>То, что Вы писали — это два разных класса.
AG>Я бы предложил так:
AG>AG>class INode // Интерфейс узла:
AG>{
AG>public:
AG> virtual std::string GetNameOfNode() const = 0;
AG> virtual std::vector<std::shared_ptr<INode>> GetVectOfChilds() const = 0;
AG> virtual void AddNode(std::shared_ptr<INode> p) = 0;
AG>};
AG>
AG>AG>class Node : public INode // Класс реализации узла (header):
AG>{
AG>public:
AG> Node(const std::string& sNameOfNode); // C-tor
AG> ~Node(); // D-tor
AG> std::string GetNameOfNode() const override;
AG> std::vector<std::shared_ptr<INode>> GetVectOfChilds() const override;
AG> void AddNode(std::shared_ptr<INode> p) override;
AG>};
AG>
AG>Здесь и у Вас, и у меня — две сушности.
AG>Но у меня — универсальный узел и интерфейс к нему.
AG>Именно наличие программного интерфейса — позволяет уменьшить связанность (coupling) в проекте.
AG>За счёт этого, получим упрощение архитектуры и уменьшение количества ошибок.
Для того, чтобы уменьшить связность, виртуальные методы не нужны:
class SubNode;
class Node
{
public:
Node(const std::string& sNameOfNode); // C-tor
~Node(); // D-tor
std::string GetNameOfNode() const;
const std::vector<SubNode>& GetVectOfChilds() const;
void AddNode(SubNode p);
private:
std::vector<SubNode> m_SubNodes;
};
class SubNode // Интерфейс узла:
{
public:
std::string GetNameOfNode() const { return m_node->GetNameOfNode(); }
const std::vector<SubNode>& GetVectOfChilds() const { return m_node->GetNameOfNode(); }
void AddNode(SubNode node) { return m_node->AddNode(node); }
public:
std::shared_ptr<Node> m_node;
};
AG>Конечно же, можно было обойтись и без интерфейса, однако так красивее и понятнее.
Нет. Если вы хотите, чтобы элемент дерева был один и тот же, то он и должен быть один и тот же. Хотите уменьшить связность, то можно сделать, как я показал. Просто и понятно. А интерфейсы нужны там, где есть коллекции разных типов обрабатываемых в едином конвейере. Скажем если листья дерева, корень дерева и промежуточные узлы хранят разную информацию, то вот тогда следует применить интерфейс в виде класса с абстрактными методами.
AG>Кроме того, имеется заложенная база — как для развития (новые типы узлов),
Вот! Я видел очень много проектов, где была заложена база для развития и это развитие никогда не наступало. Более того, через несколько лет оказывалось, что развивать надо совсем не то, что предполагалось изначально, а там, где оно предполагалось развития никакого не надо. В результате вместо упрощения имеем усложнение из-за дополнительных классов, которые никому не нужны.
AG>так и для тестирования основы нашего проекта.
Про связь с тестированием я не понял.