Re[5]: бессмысленные интерфейсы
От: B0FEE664  
Дата: 19.02.22 18:12
Оценка:
Здравствуйте, 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>так и для тестирования основы нашего проекта.

Про связь с тестированием я не понял.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.